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

Revision 5143, 175.8 KB (checked in by jwrdegoede, 7 years ago)

Modify initscript chkconfig comments to not make the service start by default, modify sensors-detect to enable the service on boot once configured and to start it at the end of sensors-detect

  • 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 - 2008  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 => "VIA VT1211 (I2C)",
1331       driver => "use-isa-instead",
1332       i2c_addrs => [0x2d],
1333       i2c_detect => sub { vt1211_i2c_detect(0, @_); },
1334     },
1335     {
1336       name => "ITE IT8712F",
1337       driver => "it87",
1338       i2c_addrs => [0x28..0x2f],
1339       i2c_detect => sub { ite_detect(0, @_); },
1340     },
1341     {
1342       name => "ITE IT8201R/IT8203R/IT8206R/IT8266R",
1343       driver => "not-a-sensor",
1344       i2c_addrs => [0x4e],
1345       i2c_detect => sub { ite_overclock_detect(@_); },
1346     },
1347     {
1348       name => "SPD EEPROM",
1349       driver => "not-a-sensor",
1350       # Can also live at 0x54-0x57, but we don't care: we only check
1351       # for SPD and EDID EEPROMs because some hardware monitoring chips
1352       # can live at 0x50-0x53.
1353       i2c_addrs => [0x50..0x53],
1354       i2c_detect => sub { eeprom_detect(@_); },
1355     },
1356     {
1357       name => "EDID EEPROM",
1358       driver => "not-a-sensor",
1359       i2c_addrs => [0x50..0x53],
1360       i2c_detect => sub { ddcmonitor_detect(@_); },
1361     },
1362     {
1363       name => "FSC Poseidon II",
1364       driver => "to-be-written",
1365       i2c_addrs => [0x73],
1366       i2c_detect => sub { fscpos_detect(@_); },
1367     },
1368     {
1369       name => "FSC Heimdal",
1370       driver => "fschmd",
1371       i2c_addrs => [0x73],
1372       i2c_detect => sub { fschmd_detect(@_); },
1373     },
1374     {
1375       name => "FSC Heracles",
1376       driver => "fschmd",
1377       i2c_addrs => [0x73],
1378       i2c_detect => sub { fschrc_detect(@_); },
1379     },
1380     {
1381       name => "ALi M5879",
1382       driver => "to-be-written",
1383       i2c_addrs => [0x2c..0x2d],
1384       i2c_detect => sub { m5879_detect(@_); },
1385     },
1386     {
1387       name => "SMSC LPC47M15x/192/292/997",
1388       driver => "smsc47m192",
1389       i2c_addrs => [0x2c..0x2d],
1390       i2c_detect => sub { smsc47m192_detect(@_); },
1391     },
1392     {
1393       name => "SMSC DME1737",
1394       driver => "dme1737",
1395       i2c_addrs => [0x2c..0x2e],
1396       i2c_detect => sub { dme1737_detect(1, @_); },
1397     },
1398     {
1399       name => "SMSC SCH5027D-NW",
1400       driver => "dme1737",
1401       i2c_addrs => [0x2c..0x2e],
1402       i2c_detect => sub { dme1737_detect(2, @_); },
1403     },
1404     {
1405       name => "Fintek F75111R/RG/N (GPIO)",
1406       driver => "not-a-sensor",
1407       i2c_addrs => [0x4e], # 0x37 not probed
1408       i2c_detect => sub { fintek_detect(1, @_); },
1409     },
1410     {
1411       name => "Fintek F75121R/F75122R/RG (VID+GPIO)",
1412       driver => "to-be-written",
1413       i2c_addrs => [0x4e], # 0x37 not probed
1414       i2c_detect => sub { fintek_detect(2, @_); },
1415     },
1416     {
1417       name => "Fintek F75373S/SG",
1418       driver => "f75375s",
1419       i2c_addrs => [0x2d..0x2e],
1420       i2c_detect => sub { fintek_detect(3, @_); },
1421     },
1422     {
1423       name => "Fintek F75375S/SP",
1424       driver => "f75375s",
1425       i2c_addrs => [0x2d..0x2e],
1426       i2c_detect => sub { fintek_detect(4, @_); },
1427     },
1428     {
1429       name => "Fintek F75387SG/RG",
1430       driver => "to-be-written",
1431       i2c_addrs => [0x2d..0x2e],
1432       i2c_detect => sub { fintek_detect(5, @_); },
1433     },
1434     {
1435       name => "Fintek F75383S/M",
1436       driver => "to-be-written",
1437       i2c_addrs => [0x4c],
1438       i2c_detect => sub { fintek_detect(6, @_); },
1439     },
1440     {
1441       name => "Fintek F75384S/M",
1442       driver => "to-be-written",
1443       i2c_addrs => [0x4d],
1444       i2c_detect => sub { fintek_detect(6, @_); },
1445     },
1446     {
1447       name => "Fintek custom power control IC",
1448       driver => "to-be-written",
1449       i2c_addrs => [0x2f],
1450       i2c_detect => sub { fintek_detect(7, @_); },
1451     },
1452     {
1453       name => "Smart Battery",
1454       driver => "smartbatt",
1455       i2c_addrs => [0x0b],
1456       i2c_detect => sub { smartbatt_detect(@_); },
1457     },
1458);
1459
1460# Special case chip information goes here and would be included in
1461# the chip_special_cases routine below
1462use vars qw(@chip_kern24_ids @chip_kern26_ids
1463            @chip_oldfsc_ids @chip_fschmd_ids);
1464@chip_kern24_ids = (
1465     {
1466       name => "Analog Devices ADM1024",
1467       driver => "adm1024",
1468       i2c_addrs => [0x2c..0x2e],
1469       i2c_detect => sub { adm1024_detect(0, @_); },
1470     },
1471     {
1472       name => "Winbond W83791D",
1473       driver => "w83781d",
1474       i2c_addrs => [0x2c..0x2f],
1475       i2c_detect => sub { w83781d_detect(7, @_); },
1476     },
1477     {
1478       name => "FSC Scylla",
1479       driver => "fscscy",
1480       i2c_addrs => [0x73],
1481       i2c_detect => sub { fscscy_detect(@_); },
1482     },
1483     {
1484       name => "IPMI BMC KCS",
1485       driver => "bmcsensors",
1486       isa_addrs => [0x0ca0],
1487       isa_detect => sub { ipmi_kcs_detect(@_); },
1488     },
1489     {
1490       name => "IPMI BMC SMIC",
1491       driver => "bmcsensors",
1492       isa_addrs => [0x0ca8],
1493       isa_detect => sub { ipmi_smic_detect(@_); },
1494     },
1495);
1496
1497@chip_kern26_ids = (
1498     {
1499       name => "Analog Devices ADM1024",
1500       driver => "lm87",
1501       i2c_addrs => [0x2c..0x2e],
1502       i2c_detect => sub { adm1024_detect(0, @_); },
1503     },
1504     {
1505       name => "Winbond W83791D",
1506       driver => "w83791d",
1507       i2c_addrs => [0x2c..0x2f],
1508       i2c_detect => sub { w83781d_detect(7, @_); },
1509     },
1510     {
1511       name => "FSC Scylla",
1512       driver => "fschmd",
1513       i2c_addrs => [0x73],
1514       i2c_detect => sub { fscscy_detect(@_); },
1515     },
1516     {
1517       name => "IPMI BMC KCS",
1518       driver => "ipmisensors",
1519       isa_addrs => [0x0ca0],
1520       isa_detect => sub { ipmi_kcs_detect(@_); },
1521     },
1522     {
1523       name => "IPMI BMC SMIC",
1524       driver => "ipmisensors",
1525       isa_addrs => [0x0ca8],
1526       isa_detect => sub { ipmi_smic_detect(@_); },
1527     },
1528);
1529
1530# sigh special case for old seperate FSC drivers to new merged one mapping
1531@chip_oldfsc_ids = (
1532     {
1533       name => "FSC Poseidon I",
1534       driver => "fscpos",
1535       i2c_addrs => [0x73],
1536       i2c_detect => sub { fscpeg_detect(@_); },
1537     },
1538     {
1539       name => "FSC Hermes",
1540       driver => "fscher",
1541       i2c_addrs => [0x73],
1542       i2c_detect => sub { fscher_detect(@_); },
1543     },
1544);
1545
1546@chip_fschmd_ids = (
1547     {
1548       name => "FSC Poseidon I",
1549       driver => "fschmd",
1550       i2c_addrs => [0x73],
1551       i2c_detect => sub { fscpeg_detect(@_); },
1552     },
1553     {
1554       name => "FSC Hermes",
1555       driver => "fschmd",
1556       i2c_addrs => [0x73],
1557       i2c_detect => sub { fscher_detect(@_); },
1558     },
1559);
1560
1561
1562# This is a list of all recognized superio chips.
1563# Each entry must have the following fields:
1564#  name: The full chip name
1565#  driver: The driver name (without .o extension). Put in
1566#      "to-be-written" if it is not yet available.
1567#      Put in "not-a-sensor" if the chip doesn't have hardware monitoring
1568#      capabilities (listing such chips here removes the need of manual
1569#      lookup when people report them).
1570#      Put in exactly "via-smbus-only" if this is a Super-I/O chip whose
1571#      hardware monitoring registers can only be accessed via the SMBus.
1572#  devid: The device ID(s) we have to match (base device)
1573#  devid_mask (optional): Bitmask to apply before checking the device ID
1574#  logdev: The logical device containing the sensors
1575#  alias_detect (optional): For chips which can be both on the ISA and the
1576#      I2C bus, a function which detectes whether two entries are the same.
1577#      The function should take three parameters: The ISA address, the
1578#      I2C bus number, and the I2C address.
1579# Entries are grouped by family. Each family entry has the following fields:
1580#  family: The family name
1581#  guess (optional): Typical logical device address. This lets us do
1582#      generic probing if we fail to recognize the chip.
1583#  enter: The password sequence to write to the address register
1584#  chips: Array of chips
1585# The order of families matters, because we stop as soon as one family
1586# succeeds. So we have to list families with shorter password sequences
1587# first.
1588@superio_ids = (
1589  {
1590    family => "National Semiconductor",
1591    enter =>
1592    {
1593      0x2e => [],
1594      0x4e => [],
1595    },
1596    chips =>
1597    [
1598      {
1599        name => "Nat. Semi. PC8374L Super IO Sensors",
1600        driver => "to-be-written",
1601        devid => 0xf1,
1602        logdev => 0x08,
1603      },
1604      {
1605        name => "Nat. Semi. PC87351 Super IO Fan Sensors",
1606        driver => "to-be-written",
1607        devid => 0xe2,
1608        logdev => 0x08,
1609      },
1610      {
1611        name => "Nat. Semi. PC87360 Super IO Fan Sensors",
1612        driver => "pc87360",
1613        devid => 0xe1,
1614        logdev => 0x09,
1615      },
1616      {
1617        name => "Nat. Semi. PC87363 Super IO Fan Sensors",
1618        driver => "pc87360",
1619        devid => 0xe8,
1620        logdev => 0x09,
1621      },
1622      {
1623        name => "Nat. Semi. PC87364 Super IO Fan Sensors",
1624        driver => "pc87360",
1625        devid => 0xe4,
1626        logdev => 0x09,
1627      },
1628      {
1629        name => "Nat. Semi. PC87365 Super IO Fan Sensors",
1630        driver => "pc87360",
1631        devid => 0xe5,
1632        logdev => 0x09,
1633      },
1634      {
1635        name => "Nat. Semi. PC87365 Super IO Voltage Sensors",
1636        driver => "pc87360",
1637        devid => 0xe5,
1638        logdev => 0x0d,
1639      },
1640      {
1641        name => "Nat. Semi. PC87365 Super IO Thermal Sensors",
1642        driver => "pc87360",
1643        devid => 0xe5,
1644        logdev => 0x0e,
1645      },
1646      {
1647        name => "Nat. Semi. PC87366 Super IO Fan Sensors",
1648        driver => "pc87360",
1649        devid => 0xe9,
1650        logdev => 0x09,
1651      },
1652      {
1653        name => "Nat. Semi. PC87366 Super IO Voltage Sensors",
1654        driver => "pc87360",
1655        devid => 0xe9,
1656        logdev => 0x0d,
1657      },
1658      {
1659        name => "Nat. Semi. PC87366 Super IO Thermal Sensors",
1660        driver => "pc87360",
1661        devid => 0xe9,
1662        logdev => 0x0e,
1663      },
1664      {
1665        name => "Nat. Semi. PC87372 Super IO Fan Sensors",
1666        driver => "to-be-written",
1667        devid => 0xf0,
1668        logdev => 0x09,
1669      },
1670      {
1671        name => "Nat. Semi. PC87373 Super IO Fan Sensors",
1672        driver => "to-be-written",
1673        devid => 0xf3,
1674        logdev => 0x09,
1675      },
1676      {
1677        name => "Nat. Semi. PC87591 Super IO",
1678        driver => "to-be-written",
1679        devid => 0xec,
1680        logdev => 0x0f,
1681      },
1682      {
1683        name => "Nat. Semi. PC87317 Super IO",
1684        driver => "not-a-sensor",
1685        devid => 0xd0,
1686      },
1687      {
1688        name => "Nat. Semi. PC97317 Super IO",
1689        driver => "not-a-sensor",
1690        devid => 0xdf,
1691      },
1692      {
1693        name => "Nat. Semi. PC8739x Super IO",
1694        driver => "not-a-sensor",
1695        devid => 0xea,
1696      },
1697      {
1698        name => "Nat. Semi. PC8741x Super IO",
1699        driver => "not-a-sensor",
1700        devid => 0xee,
1701      },
1702      {
1703        name => "Nat. Semi. PC87427 Super IO Fan Sensors",
1704        driver => "pc87427",
1705        devid => 0xf2,
1706        logdev => 0x09,
1707      },
1708      {
1709        name => "Nat. Semi. PC87427 Super IO Health Sensors",
1710        driver => "to-be-written",
1711        devid => 0xf2,
1712        logdev => 0x14,
1713      },
1714    ],
1715  },
1716  {
1717    family => "SMSC",
1718    enter =>
1719    {
1720      0x2e => [0x55],
1721      0x4e => [0x55],
1722    },
1723    chips =>
1724    [
1725      {
1726        name => "SMSC DME1737 Super IO",
1727        # Hardware monitoring features are accessed on the SMBus
1728        driver => "via-smbus-only",
1729        devid => 0x78,
1730      },
1731      {
1732        name => "SMSC DME1737 Super IO",
1733        # The DME1737 shows up twice in this list because it can return either
1734        # 0x78 or 0x77 as its device ID.
1735        # Hardware monitoring features are accessed on the SMBus
1736        driver => "via-smbus-only",
1737        devid => 0x77,
1738      },
1739      {
1740        name => "SMSC FDC37B72x Super IO",
1741        driver => "not-a-sensor",
1742        devid => 0x4c,
1743      },
1744      {
1745        name => "SMSC FDC37B78x Super IO",
1746        driver => "not-a-sensor",
1747        devid => 0x44,
1748      },
1749      {
1750        name => "SMSC FDC37C672 Super IO",
1751        driver => "not-a-sensor",
1752        devid => 0x40,
1753      },
1754      {
1755        name => "SMSC FDC37M707 Super IO",
1756        driver => "not-a-sensor",
1757        devid => 0x42,
1758      },
1759      {
1760        name => "SMSC FDC37M81x Super IO",
1761        driver => "not-a-sensor",
1762        devid => 0x4d,
1763      },
1764      {
1765        name => "SMSC LPC47B27x Super IO Fan Sensors",
1766        driver => "smsc47m1",
1767        devid => 0x51,
1768        logdev => 0x0a,
1769      },
1770      {
1771        name => "SMSC LPC47B34x Super IO",
1772        driver => "not-a-sensor",
1773        devid => 0x56,
1774      },
1775      {
1776        name => "SMSC LPC47B357/M967 Super IO",
1777        driver => "not-a-sensor",
1778        devid => 0x5d,
1779      },
1780      {
1781        name => "SMSC LPC47B367-NC Super IO",
1782        driver => "not-a-sensor",
1783        devid => 0x6d,
1784      },
1785      {
1786        name => "SMSC LPC47B37x Super IO Fan Sensors",
1787        driver => "to-be-written",
1788        devid => 0x52,
1789        logdev => 0x0a,
1790      },
1791      {
1792        name => "SMSC LPC47B397-NC Super IO",
1793        driver => "smsc47b397",
1794        devid => 0x6f,
1795        logdev => 0x08,
1796      },
1797      {
1798        name => "SMSC LPC47M10x/112/13x Super IO Fan Sensors",
1799        driver => "smsc47m1",
1800        devid => 0x59,
1801        logdev => 0x0a,
1802      },
1803      {
1804        name => "SMSC LPC47M14x Super IO Fan Sensors",
1805        driver => "smsc47m1",
1806        devid => 0x5f,
1807        logdev => 0x0a,
1808      },
1809      {
1810        name => "SMSC LPC47M15x/192/997 Super IO Fan Sensors",
1811        driver => "smsc47m1",
1812        devid => 0x60,
1813        logdev => 0x0a,
1814      },
1815      {
1816        name => "SMSC LPC47M172 Super IO Fan Sensors",
1817        driver => "to-be-written",
1818        devid => 0x14,
1819        logdev => 0x0a,
1820      },
1821      {
1822        name => "SMSC LPC47M182 Super IO Fan Sensors",
1823        driver => "to-be-written",
1824        devid => 0x74,
1825        logdev => 0x0a,
1826      },
1827      {
1828        name => "SMSC LPC47M292 Super IO Fan Sensors",
1829        driver => "smsc47m1",
1830        devid => 0x6b,
1831        logdev => 0x0a,
1832      },
1833      {
1834        name => "SMSC LPC47M584-NC Super IO",
1835        # No datasheet
1836        devid => 0x76,
1837      },
1838      {
1839        name => "SMSC LPC47N252 Super IO Fan Sensors",
1840        driver => "to-be-written",
1841        devid => 0x0e,
1842        logdev => 0x09,
1843      },
1844      {
1845        name => "SMSC LPC47S42x Super IO Fan Sensors",
1846        driver => "to-be-written",
1847        devid => 0x57,
1848        logdev => 0x0a,
1849      },
1850      {
1851        name => "SMSC LPC47S45x Super IO Fan Sensors",
1852        driver => "to-be-written",
1853        devid => 0x62,
1854        logdev => 0x0a,
1855      },
1856      {
1857        name => "SMSC LPC47U33x Super IO Fan Sensors",
1858        driver => "to-be-written",
1859        devid => 0x54,
1860        logdev => 0x0a,
1861      },
1862      {
1863        name => "SMSC SCH3112 Super IO",
1864        driver => "dme1737",
1865        devid => 0x7c,
1866        logdev => 0x0a,
1867      },
1868      {
1869        name => "SMSC SCH3114 Super IO",
1870        driver => "dme1737",
1871        devid => 0x7d,
1872        logdev => 0x0a,
1873      },
1874      {
1875        name => "SMSC SCH3116 Super IO",
1876        driver => "dme1737",
1877        devid => 0x7f,
1878        logdev => 0x0a,
1879      },
1880      {
1881        name => "SMSC SCH4307 Super IO Fan Sensors",
1882        driver => "to-be-written",
1883        devid => 0x90,
1884        logdev => 0x08,
1885      },
1886      {
1887        name => "SMSC SCH5027D-NW Super IO",
1888        # Hardware monitoring features are accessed on the SMBus
1889        driver => "via-smbus-only",
1890        devid => 0x89,
1891      },
1892      {
1893        name => "SMSC SCH5307-NS Super IO",
1894        driver => "smsc47b397",
1895        devid => 0x81,
1896        logdev => 0x08,
1897      },
1898      {
1899        name => "SMSC SCH5317 Super IO",
1900        driver => "smsc47b397",
1901        devid => 0x85,
1902        logdev => 0x08,
1903      },
1904      {
1905        name => "SMSC SCH5317 Super IO",
1906        # The SCH5317 shows up twice in this list because it can return either
1907        # 0x85 or 0x8c as its device ID.
1908        driver => "smsc47b397",
1909        devid => 0x8c,
1910        logdev => 0x08,
1911      },
1912      {
1913        name => "SMSC SCH5504-NS Super IO",
1914        # No datasheet
1915        driver => "not-a-sensor",
1916        devid => 0x79,
1917      },
1918      {
1919        name => "SMSC SCH5514D-NS Super IO",
1920        # No datasheet
1921        driver => "not-a-sensor",
1922        devid => 0x83,
1923      },
1924    ],
1925    # Non-standard SMSC detection callback and chip list. These chips differ
1926    # from the standard ones listed above in that the device ID register
1927    # address is 0x0d instead of 0x20 (as specified by the ISA PNP spec).
1928    ns_detect => \&smsc_ns_detect_superio,
1929    ns_chips =>
1930    [
1931      {
1932        name => "SMSC FDC37C665 Super IO",
1933        driver => "not-a-sensor",
1934        devid => 0x65,
1935      },
1936      {
1937        name => "SMSC FDC37C666 Super IO",
1938        driver => "not-a-sensor",
1939        devid => 0x66,
1940      },
1941      {
1942        name => "SMSC FDC37C669 Super IO",
1943        driver => "not-a-sensor",
1944        devid => 0x03,
1945      },
1946      {
1947        name => "SMSC FDC37N769 Super IO",
1948        driver => "not-a-sensor",
1949        devid => 0x28,
1950      },
1951      {
1952        name => "SMSC LPC47N227 Super IO",
1953        driver => "not-a-sensor",
1954        devid => 0x5a,
1955      },
1956    ],
1957  },
1958  {
1959    family => "VIA/Winbond/Fintek",
1960    guess => 0x290,
1961    enter =>
1962    {
1963      0x2e => [0x87, 0x87],
1964      0x4e => [0x87, 0x87],
1965    },
1966    chips =>
1967    [
1968      {
1969        name => "VIA VT1211 Super IO Sensors",
1970        driver => "vt1211",
1971        devid => 0x3c,
1972        logdev => 0x0b,
1973        alias_detect => sub { vt1211_alias_detect(0, @_); },
1974      },
1975      {
1976        name => "Winbond W83627HF/F/HG/G Super IO Sensors",
1977        driver => "w83627hf",
1978        devid => 0x52,
1979        logdev => 0x0b,
1980        alias_detect => sub { w83781d_alias_detect(3, @_); },
1981      },
1982      {
1983        name => "Winbond W83627THF/THG Super IO Sensors",
1984        driver => "w83627hf",
1985        devid => 0x82,
1986        logdev => 0x0b,
1987      },
1988      {
1989        name => "Winbond W83637HF/HG Super IO Sensors",
1990        driver => "w83627hf",
1991        devid => 0x70,
1992        logdev => 0x0b,
1993      },
1994      {
1995        name => "Winbond W83687THF Super IO Sensors",
1996        driver => "w83627hf",
1997        devid => 0x85,
1998        logdev => 0x0b,
1999      },
2000      {
2001        name => "Winbond W83697HF/F/HG Super IO Sensors",
2002        driver => "w83627hf",
2003        devid => 0x60,
2004        logdev => 0x0b,
2005      },
2006      {
2007        name => "Winbond W83697SF/UF/UG Super IO PWM",
2008        driver => "to-be-written",
2009        devid => 0x68,
2010        logdev => 0x0b,
2011      },
2012      {
2013        name => "Winbond W83627EHF/EF/EHG/EG Super IO Sensors",
2014        driver => "w83627ehf",
2015        # W83627EHF datasheet says 0x886x but 0x8853 was seen, thus the
2016        # broader mask. W83627EHG was seen with ID 0x8863.
2017        devid => 0x8840,
2018        devid_mask => 0xFFC0,
2019        logdev => 0x0b,
2020        alias_detect => sub { w83781d_alias_detect(9, @_); },
2021      },
2022      {
2023        name => "Winbond W83627DHG Super IO Sensors",
2024        driver => "w83627ehf",
2025        devid => 0xA020,
2026        devid_mask => 0xFFF0,
2027        logdev => 0x0b,
2028        alias_detect => sub { w83781d_alias_detect(10, @_); },
2029      },
2030      {
2031        name => "Winbond W83L517D Super IO",
2032        driver => "not-a-sensor",
2033        devid => 0x61,
2034      },
2035      {
2036        name => "Fintek F71805F/FG Super IO Sensors",
2037        driver => "f71805f",
2038        devid => 0x0406,
2039        logdev => 0x04,
2040      },
2041      {
2042        name => "Fintek F71862FG Super IO Sensors",
2043        driver => "to-be-written",
2044        devid => 0x0601,
2045        logdev => 0x04,
2046      },
2047      {
2048        name => "Fintek F71806FG/F71872FG Super IO Sensors",
2049        driver => "f71805f",
2050        devid => 0x0341,
2051        logdev => 0x04,
2052      },
2053      {
2054        name => "Fintek F71858DG Super IO Sensors",
2055        driver => "to-be-written",
2056        devid => 0x0507,
2057        logdev => 0x02,
2058      },
2059      {
2060        name => "Fintek F71882FG/F71883FG Super IO Sensors",
2061        driver => "f71882fg",
2062        devid => 0x0541,
2063        logdev => 0x04,
2064      },
2065      {
2066        name => "Fintek F81216D Super IO",
2067        driver => "not-a-sensor",
2068        devid => 0x0208,
2069      },
2070      {
2071        name => "Fintek F81218D Super IO",
2072        driver => "not-a-sensor",
2073        devid => 0x0206,
2074      },
2075      {
2076        # Shouldn't be in this family, but seems to be still.
2077        name => "ITE IT8708F Super IO",
2078        driver => "not-a-sensor",
2079        devid => 0x8708,
2080      },
2081    ],
2082  },
2083  {
2084    family => "ITE",
2085    guess => 0x290,
2086    enter =>
2087    {
2088      0x2e => [0x87, 0x01, 0x55, 0x55],
2089      0x4e => [0x87, 0x01, 0x55, 0xaa],
2090    },
2091    chips =>
2092    [
2093      {
2094        name => "ITE IT8702F Super IO Sensors",
2095        driver => "to-be-written",
2096        devid => 0x8702,
2097        logdev => 0x04,
2098      },
2099      {
2100        name => "ITE IT8705F Super IO Sensors",
2101        driver => "it87",
2102        devid => 0x8705,
2103        logdev => 0x04,
2104      },
2105      {
2106        name => "ITE IT8712F Super IO Sensors",
2107        driver => "it87",
2108        devid => 0x8712,
2109        logdev => 0x04,
2110        alias_detect => sub { ite_alias_detect(0, @_); },
2111      },
2112      {
2113        name => "ITE IT8716F Super IO Sensors",
2114        driver => "it87",
2115        devid => 0x8716,
2116        logdev => 0x04,
2117      },
2118      {
2119        name => "ITE IT8718F Super IO Sensors",
2120        driver => "it87",
2121        devid => 0x8718,
2122        logdev => 0x04,
2123      },
2124      {
2125        name => "ITE IT8726F Super IO Sensors",
2126        driver => "it87",
2127        devid => 0x8726,
2128        logdev => 0x04,
2129      },
2130    ],
2131  },
2132);
2133
2134# Drivers for CPU embedded sensors
2135# Each entry must have the following fields:
2136#  name: The CPU family name
2137#  driver: The driver name. Put "to-be-written" if no driver is available.
2138#  detect: Detection callback function. No parameter will be passed to
2139#          this function, it must use global lists of PCI devices, CPU,
2140#          etc. It must return a confidence value, undef if no supported
2141#          CPU is found.
2142@cpu_ids = (
2143  {
2144    name => "Silicon Integrated Systems SIS5595",
2145    driver => "sis5595",
2146    detect => sub { sis5595_pci_detect(); },
2147  },
2148  {
2149    name => "VIA VT82C686 Integrated Sensors",
2150    driver => "via686a",
2151    detect => sub { via686a_pci_detect(); },
2152  },
2153  {
2154    name => "VIA VT8231 Integrated Sensors",
2155    driver => "vt8231",
2156    detect => sub { via8231_pci_detect(); },
2157  },
2158  {
2159    name => "AMD K8 thermal sensors",
2160    driver => "k8temp",
2161    detect => sub { k8temp_pci_detect(); },
2162  },
2163  {
2164    name => "AMD K10 thermal sensors",
2165    driver => "to-be-written",
2166    detect => sub { k10temp_pci_detect(); },
2167  },
2168  {
2169    name => "Intel Core family thermal sensor",
2170    driver => "coretemp",
2171    detect => sub { coretemp_detect(); },
2172  },
2173  {
2174    name => "Intel AMB FB-DIMM thermal sensor",
2175    driver => "to-be-written",
2176    detect => sub { intel_amb_detect(); },
2177  },
2178);
2179
2180#######################
2181# AUXILIARY FUNCTIONS #
2182#######################
2183
2184sub swap_bytes
2185{
2186  return (($_[0] & 0xff00) >> 8) + (($_[0] & 0x00ff) << 8)
2187}
2188
2189# $_[0] is the sought value
2190# @_[1..] is the list to seek in
2191# Returns: 0 on failure, 1 if found.
2192# Note: Every use of this sub probably indicates the use of the wrong
2193#       datastructure
2194sub contains
2195{
2196  my $sought = shift;
2197  foreach (@_) {
2198    return 1 if $sought eq $_;
2199  }
2200  return 0;
2201}
2202
2203sub parse_not_to_scan
2204{
2205  my ($min,$max,$to_parse) = @_;
2206  my @ranges = split /\s*,\s*/, $to_parse;
2207  my @res;
2208  my $range;
2209  foreach $range (@ranges) {
2210    my ($start,$end) = split /\s*-s*/, $range;
2211    $start = oct $start if $start =~ /^0/;
2212    if (defined $end) {
2213      $end = oct $end if $end =~ /^0/;
2214      $start = $min if $start < $min;
2215      $end = $max if $end > $max;
2216      push @res, ($start+0..$end+0);
2217    } else {
2218      push @res, $start+0 if $start >= $min and $start <= $max;
2219    }
2220  }
2221  return sort { $a <=> $b } @res;
2222}
2223
2224# @_[0]: Reference to list 1
2225# @_[1]: Reference to list 2
2226# Result: 0 if they have no elements in common, 1 if they have
2227# Elements must be numeric.
2228sub any_list_match
2229{
2230  my ($list1,$list2) = @_;
2231  my ($el1,$el2);
2232  foreach $el1 (@$list1) {
2233    foreach $el2 (@$list2) {
2234      return 1 if $el1 == $el2;
2235    }
2236  }
2237  return 0;
2238}
2239
2240###################
2241# I/O port access #
2242###################
2243
2244sub initialize_ioports
2245{
2246  sysopen (IOPORTS, "/dev/port", O_RDWR)
2247    or die "/dev/port: $!\n";
2248  binmode IOPORTS;
2249}
2250
2251sub close_ioports
2252{
2253  close (IOPORTS)
2254    or print "Warning: $!\n";
2255}
2256
2257# $_[0]: port to read
2258# Returns: -1 on failure, read value on success.
2259sub inb
2260{
2261  my ($res,$nrchars);
2262  sysseek IOPORTS, $_[0], 0 or return -1;
2263  $nrchars = sysread IOPORTS, $res, 1;
2264  return -1 if not defined $nrchars or $nrchars != 1;
2265  $res = unpack "C",$res ;
2266  return $res;
2267}
2268
2269# $_[0]: port to write
2270# $_[1]: value to write
2271# Returns: -1 on failure, 0 on success.
2272sub outb
2273{
2274  my $towrite = pack "C", $_[1];
2275  sysseek IOPORTS, $_[0], 0 or return -1;
2276  my $nrchars = syswrite IOPORTS, $towrite, 1;
2277  return -1 if not defined $nrchars or $nrchars != 1;
2278  return 0;
2279}
2280
2281# $_[0]: Address register
2282# $_[1]: Data register
2283# $_[2]: Register to read
2284# Returns: read value
2285sub isa_read_byte
2286{
2287  outb $_[0],$_[2];
2288  return inb $_[1];
2289}
2290
2291# $_[0]: Address register
2292# $_[1]: Data register
2293# $_[2]: Register to write
2294# $_[3}: Value to write
2295# Returns: nothing
2296sub isa_write_byte
2297{
2298  outb $_[0],$_[2];
2299  outb $_[1],$_[3];
2300}
2301
2302#################
2303# AUTODETECTION #
2304#################
2305
2306use vars qw($modules_conf $dev_i2c $sysfs_root);
2307
2308sub initialize_conf
2309{
2310  my $use_devfs = 0;
2311  open(local *INPUTFILE, "/proc/mounts") or die "Can't access /proc/mounts!";
2312  local $_;
2313  while (<INPUTFILE>) {
2314    if (m@^\w+ /dev devfs @) {
2315      $use_devfs = 1;
2316      $dev_i2c = '/dev/i2c/';
2317    }
2318    if (m@^\S+ (/\w+) sysfs @) {
2319      $sysfs_root = $1;
2320    }
2321  }
2322  close INPUTFILE;
2323
2324  my $use_udev = 0;
2325  if (open(*INPUTFILE, '/etc/udev/udev.conf')) {
2326    while (<INPUTFILE>) {
2327      if (m/^\s*udev_db\s*=\s*\"([^"]*)\"/ || m/^\s*udev_db\s*=\s*(\S+)/) {
2328        if (-e $1) {
2329          $use_udev = 1;
2330          $dev_i2c = '/dev/i2c-';
2331        }
2332        last;
2333      }
2334    }
2335    close INPUTFILE;
2336  }
2337 
2338  if (!$use_udev) {
2339    # Try some known default udev db locations, just in case
2340    if (-e '/dev/.udev.tdb' || -e '/dev/.udev'
2341     || -e '/dev/.udevdb') {
2342      $use_udev = 1;
2343      $dev_i2c = '/dev/i2c-';
2344    }
2345  }
2346
2347  if (kernel_version_at_least(2, 6, 0)) {
2348    $modules_conf = '/etc/modprobe.conf';
2349  } else {
2350    $modules_conf = '/etc/modules.conf';
2351  }
2352
2353  if (!($use_devfs || $use_udev)) {
2354    if (! -c '/dev/i2c-0' && -x '/sbin/MAKEDEV') {
2355      system("/sbin/MAKEDEV i2c");
2356    }
2357    if (! -c '/dev/i2c-0' && -x '/dev/MAKEDEV') {
2358      system("/dev/MAKEDEV i2c");
2359    }
2360    if (-c '/dev/i2c-0') {
2361      $dev_i2c = '/dev/i2c-';
2362    } else { # default
2363      print "No i2c device files found.\n";
2364      exit -1;
2365    }
2366  }
2367}
2368
2369# [0] -> VERSION
2370# [1] -> PATCHLEVEL
2371# [2] -> SUBLEVEL
2372# [3] -> EXTRAVERSION
2373#
2374use vars qw(@kernel_version $kernel_arch);
2375
2376sub initialize_kernel_version
2377{
2378  `uname -r` =~ /(\d+)\.(\d+)\.(\d+)(.*)/;
2379  @kernel_version = ($1, $2, $3, $4);
2380  chomp($kernel_arch = `uname -m`);
2381}
2382
2383sub kernel_version_at_least
2384{
2385  my ($vers, $plvl, $slvl) = @_;
2386  return 1 if ($kernel_version[0]  > $vers ||
2387                ($kernel_version[0] == $vers && 
2388                  ($kernel_version[1]  > $plvl || 
2389                    ($kernel_version[1] == $plvl && 
2390                      ($kernel_version[2] >= $slvl)))));
2391  return 0;
2392}
2393
2394# @cpu is a list of reference to hashes, one hash per CPU.
2395# Each entry has the following keys: vendor_id, cpu family, model,
2396# model name and stepping, directly taken from /proc/cpuinfo.
2397use vars qw(@cpu);
2398
2399sub initialize_cpu_list
2400{
2401  open(local *INPUTFILE, "/proc/cpuinfo") or die "Can't access /proc/cpuinfo!";
2402  local $_;
2403  my $entry;
2404
2405  while (<INPUTFILE>) {
2406    if (m/^processor\s*:\s*(\d+)/) {
2407      push @cpu, $entry if scalar keys(%{$entry}); # Previous entry
2408      $entry = {}; # New entry
2409      next;
2410    }
2411    if (m/^(vendor_id|cpu family|model|model name|stepping)\s*:\s*(.+)$/) {
2412      my $k = $1;
2413      my $v = $2;
2414      $v =~ s/\s+/ /g;  # Merge multiple spaces
2415      $v =~ s/ $//;     # Trim trailing space
2416      $entry->{$k} = $v;
2417      next;
2418    }
2419  }
2420  push @cpu, $entry if scalar keys(%{$entry}); # Last entry
2421  close INPUTFILE;
2422}
2423
2424# @i2c_adapters is a list of references to hashes, one hash per I2C/SMBus
2425# adapter present on the system. Each entry has the following keys: name
2426# (directly taken from either /proc/bus/i2c or /sys/class/i2c-adapter) and
2427# driver.
2428use vars qw(@i2c_adapters);
2429
2430sub initialize_i2c_adapters_list
2431{
2432  my $entry;
2433  local $_;
2434
2435  if (defined $sysfs_root) {
2436    my $class_dir = "${sysfs_root}/class/i2c-adapter";
2437    opendir(local *ADAPTERS, $class_dir) or return;
2438
2439    while (defined($_ = readdir(ADAPTERS))) {
2440      next unless m/^i2c-(\d+)$/;
2441      $entry = {}; # New entry
2442      $entry->{'name'} = sysfs_device_attribute("${class_dir}/i2c-$1", "name")
2443                      || sysfs_device_attribute("${class_dir}/i2c-$1/device", "name");
2444      next if $entry->{'name'} eq "ISA main adapter";
2445      $entry->{'driver'} = find_adapter_driver($entry->{'name'});
2446      $i2c_adapters[$1] = $entry;
2447    }
2448    closedir(ADAPTERS);
2449  } else {
2450    open(local *INPUTFILE, "/proc/bus/i2c") or return;
2451
2452    while (<INPUTFILE>) {
2453      my ($nr, $type, $name) = /^i2c-(\d+)\s+(\S+)\s+(.*?) *(\t|$)/;
2454      next if ($type eq "dummy" || $type eq "isa");
2455      $entry = {}; # New entry
2456      $entry->{'name'} = $name;
2457      $entry->{'driver'} = find_adapter_driver($name);
2458      $i2c_adapters[$nr] = $entry;
2459    }
2460    close(INPUTFILE);
2461  }
2462}
2463
2464###########
2465# MODULES #
2466###########
2467
2468use vars qw(%modules_list %modules_supported);
2469
2470sub initialize_modules_list
2471{
2472  open(local *INPUTFILE, "/proc/modules") or return;
2473  local $_;
2474  while (<INPUTFILE>) {
2475    tr/_/-/;
2476    $modules_list{$1} = 1 if m/^(\S*)/;
2477  }
2478}
2479
2480sub initialize_modules_supported
2481{
2482  foreach my $chip (@chip_ids) {
2483    $modules_supported{$chip->{driver}}++;
2484  }
2485}
2486
2487#################
2488# SYSFS HELPERS #
2489#################
2490
2491# From a sysfs device path, return the driver name, or undef
2492sub sysfs_device_driver($)
2493{
2494  my $device = shift;
2495 
2496  my $link = readlink("$device/driver");
2497  return unless defined $link;
2498  return basename($link);
2499}
2500
2501# From a sysfs device path and an attribute name, return the attribute
2502# value, or undef
2503sub sysfs_device_attribute($$)
2504{
2505  my ($device, $attr) = @_;
2506  my $value;
2507
2508  open(local *FILE, "$device/$attr") or return;
2509  return unless defined($value = <FILE>);
2510  close(FILE);
2511
2512  chomp($value);
2513  return $value;
2514}
2515
2516##############
2517# PCI ACCESS #
2518##############
2519
2520use vars qw(%pci_list);
2521
2522# This function returns a list of hashes. Each hash has some PCI information:
2523# 'domain', 'bus', 'slot' and 'func' uniquely identify a PCI device in a
2524# computer; 'vendid' and 'devid' uniquely identify a type of device.
2525# 'class' lets us spot unknown SMBus adapters.
2526# This function is used when sysfs is available (Linux 2.6).
2527sub read_sys_dev_pci($)
2528{
2529  my $devices = shift;
2530  my ($dev, @pci_list);
2531
2532  opendir(local *DEVICES, "$devices")
2533    or die "$devices: $!";
2534
2535  while (defined($dev = readdir(DEVICES))) {
2536    my %record;
2537    next unless $dev =~
2538      m/^(?:([\da-f]+):)?([\da-f]+):([\da-f]+)\.([\da-f]+)$/;
2539
2540    $record{domain} = hex $1;
2541    $record{bus} = hex $2;
2542    $record{slot} = hex $3;
2543    $record{func} = hex $4;
2544
2545    $record{vendid} = oct sysfs_device_attribute("$devices/$dev", "vendor");
2546    $record{devid} = oct sysfs_device_attribute("$devices/$dev", "device");
2547    $record{class} = (oct sysfs_device_attribute("$devices/$dev", "class"))
2548                     >> 8;
2549
2550    push @pci_list, \%record;
2551  }
2552
2553  return \@pci_list;
2554}
2555
2556# This function returns a list of hashes. Each hash has some PCI information:
2557# 'bus', 'slot' and 'func' uniquely identify a PCI device in a computer;
2558# 'vendid' and 'devid' uniquely identify a type of device.
2559# This function is used when sysfs is not available (Linux 2.4).
2560sub read_proc_dev_pci
2561{
2562  my ($dfn, $vend, @pci_list);
2563  open(local *INPUTFILE, "/proc/bus/pci/devices")
2564    or die "/proc/bus/pci/devices: $!";
2565  local $_;
2566  while (<INPUTFILE>) {
2567    my %record;
2568    ($dfn, $vend) = map { hex } (split) [0..1];
2569    $record{bus} = $dfn >> 8;
2570    $record{slot} = ($dfn & 0xf8) >> 3;
2571    $record{func} = $dfn & 0x07;
2572    $record{vendid} = $vend >> 16;
2573    $record{devid} = $vend & 0xffff;
2574   
2575    push @pci_list, \%record;
2576  }
2577  return \@pci_list;
2578}
2579
2580sub initialize_proc_pci
2581{
2582  my $pci_list;
2583
2584  if (defined $sysfs_root) {
2585    $pci_list = read_sys_dev_pci("$sysfs_root/bus/pci/devices");
2586  } else {
2587    $pci_list = read_proc_dev_pci();
2588  }
2589
2590  # Note that we lose duplicate devices at this point, but we don't
2591  # really care. What matters to us is which unique devices are present,
2592  # not how many of each.
2593  %pci_list = map {
2594    sprintf("%04x:%04x", $_->{vendid}, $_->{devid}) => $_
2595  } @{$pci_list};
2596}
2597
2598#####################
2599# ADAPTER DETECTION #
2600#####################
2601
2602sub adapter_pci_detection_sis_96x
2603{
2604  my $driver="";
2605
2606  # first, determine which driver if any...
2607  if (kernel_version_at_least(2,6,0)) {
2608    if (exists $pci_list{"1039:0016"}) {
2609      $driver = "i2c-sis96x";
2610    } elsif (exists $pci_list{"1039:0008"}) {
2611      $driver = "i2c-sis5595";
2612    }
2613  } elsif (kernel_version_at_least(2,4,0)) {
2614    if (exists $pci_list{"1039:0008"}) {
2615      if ((exists $pci_list{"1039:0645"}) ||
2616          (exists $pci_list{"1039:0646"}) ||
2617          (exists $pci_list{"1039:0648"}) ||
2618          (exists $pci_list{"1039:0650"}) ||
2619          (exists $pci_list{"1039:0651"}) ||
2620          (exists $pci_list{"1039:0655"}) ||
2621          (exists $pci_list{"1039:0661"}) ||
2622          (exists $pci_list{"1039:0735"}) ||
2623          (exists $pci_list{"1039:0745"}) ||
2624          (exists $pci_list{"1039:0746"})) {
2625        $driver = "i2c-sis645";
2626      } else {
2627        $driver = "i2c-sis5595";
2628      }
2629    } elsif ((exists $pci_list{"1039:0016"}) ||
2630             (exists $pci_list{"1039:0018"})) {
2631      $driver = "i2c-sis645";
2632    }
2633  }
2634
2635  # then, add the appropriate entries to @pci_adapters
2636  if ($driver eq "i2c-sis5595") {
2637    push @pci_adapters, @pci_adapters_sis5595;
2638  } elsif ($driver eq "i2c-sis645") {
2639    push @pci_adapters, @pci_adapters_sis645;
2640  } elsif ($driver eq "i2c-sis96x") {
2641    push @pci_adapters, @pci_adapters_sis96x;
2642  }
2643}
2644
2645# Build and return a PCI device's bus ID
2646sub pci_busid($)
2647{
2648  my $device = shift;
2649  my $busid;
2650
2651  $busid = sprintf("\%02x:\%02x.\%x",
2652                   $device->{bus}, $device->{slot}, $device->{func});
2653  $busid = sprintf("\%04x:", $device->{domain}) . $busid
2654    if defined $device->{domain};
2655
2656  return $busid;
2657}
2658
2659sub adapter_pci_detection
2660{
2661  my ($key, $device, $try, @res, %smbus);
2662  print "Probing for PCI bus adapters...\n";
2663
2664  # Custom detection routine for some SiS chipsets
2665  adapter_pci_detection_sis_96x();
2666
2667  # Build a list of detected SMBus devices
2668  foreach $key (keys %pci_list) {
2669    $device = $pci_list{$key};
2670    $smbus{$key}++
2671      if exists $device->{class} && $device->{class} == 0x0c05; # SMBus
2672  }
2673
2674  # Loop over the known I2C/SMBus adapters
2675  foreach $try (@pci_adapters) {
2676    $key = sprintf("%04x:%04x", $try->{vendid}, $try->{devid});
2677    if (exists $pci_list{$key}) {
2678        $device = $pci_list{$key};
2679        printf "Use driver `\%s' for device \%s: \%s\n",
2680               $try->{driver}, pci_busid($device), $try->{procid};
2681        if ($try->{driver} eq "to-be-tested") {
2682          print "\nWe are currently looking for testers for this adapter!\n".
2683                "Please check http://www.lm-sensors.org/wiki/Devices\n".
2684                "and/or contact us if you want to help.\n\n";
2685          print "Continue... ";
2686          <STDIN>;
2687          print "\n";
2688        }
2689        push @res,$try->{driver};
2690
2691        # Delete from detected SMBus device list
2692        delete $smbus{$key};
2693    }
2694  }
2695
2696  # Now see if there are unknown SMBus devices left
2697  foreach $key (keys %smbus) {
2698    $device = $pci_list{$key};
2699    printf "Found unknown SMBus adapter \%04x:\%04x at \%s.\n",
2700           $device->{vendid}, $device->{devid}, pci_busid($device);
2701  }
2702 
2703  if (! @res) {
2704    print "Sorry, no known PCI bus adapters found.\n";
2705  }
2706  return @res;
2707}
2708
2709# $_[0]: Adapter description as found in /proc/bus/i2c or sysfs
2710sub find_adapter_driver
2711{
2712  my $adapter;
2713  for $adapter (@pci_adapters) {
2714    return $adapter->{driver}
2715      if (exists $adapter->{match} && $_[0] =~ $adapter->{match});
2716  }
2717  return "UNKNOWN";
2718}
2719
2720#############################
2721# I2C AND SMBUS /DEV ACCESS #
2722#############################
2723
2724# This should really go into a separate module/package.
2725
2726# These are copied from <linux/i2c-dev.h>
2727
2728use constant IOCTL_I2C_SLAVE    => 0x0703;
2729use constant IOCTL_I2C_FUNCS    => 0x0705;
2730use constant IOCTL_I2C_SMBUS    => 0x0720;
2731
2732use constant SMBUS_READ         => 1;
2733use constant SMBUS_WRITE        => 0;
2734
2735use constant SMBUS_QUICK        => 0;
2736use constant SMBUS_BYTE         => 1;
2737use constant SMBUS_BYTE_DATA    => 2;
2738use constant SMBUS_WORD_DATA    => 3;
2739
2740use constant I2C_FUNC_SMBUS_QUICK       => 0x00010000;
2741use constant I2C_FUNC_SMBUS_READ_BYTE   => 0x00020000;
2742
2743# Get the i2c adapter's functionalities
2744# $_[0]: Reference to an opened filehandle
2745# Returns: -1 on failure, functionality bitfield on success.
2746sub i2c_get_funcs($)
2747{
2748  my $file = shift;
2749  my $funcs = pack "L", 0; # Allocate space
2750
2751  ioctl $file, IOCTL_I2C_FUNCS, $funcs or return -1;
2752  $funcs = unpack "L", $funcs;
2753
2754  return $funcs;
2755}
2756
2757# Select the device to communicate with through its address.
2758# $_[0]: Reference to an opened filehandle
2759# $_[1]: Address to select
2760# Returns: 0 on failure, 1 on success.
2761sub i2c_set_slave_addr
2762{
2763  my ($file,$addr) = @_;
2764  $addr += 0; # Make sure it's a number not a string
2765  ioctl $file, IOCTL_I2C_SLAVE, $addr or return 0;
2766  return 1;
2767}
2768
2769# i2c_smbus_access is based upon the corresponding C function (see
2770# <linux/i2c-dev.h>). You should not need to call this directly.
2771# Exact calling conventions are intricate; read i2c-dev.c if you really need
2772# to know.
2773# $_[0]: Reference to an opened filehandle
2774# $_[1]: SMBUS_READ for reading, SMBUS_WRITE for writing
2775# $_[2]: Command (usually register number)
2776# $_[3]: Transaction kind (SMBUS_BYTE, SMBUS_BYTE_DATA, etc.)
2777# $_[4]: Reference to an array used for input/output of data
2778# Returns: 0 on failure, 1 on success.
2779# Note that we need to get back to Integer boundaries through the 'x2'
2780# in the pack. This is very compiler-dependent; I wish there was some other
2781# way to do this.
2782sub i2c_smbus_access
2783{
2784  my ($file,$read_write,$command,$size,$data) = @_;
2785  my $data_array = pack "C32", @$data;
2786  my $ioctl_data = pack "C2x2Ip", ($read_write,$command,$size,$data_array);
2787  ioctl $file, IOCTL_I2C_SMBUS, $ioctl_data or return 0;
2788  @{$_[4]} = unpack "C32",$data_array;
2789  return 1;
2790}
2791
2792# $_[0]: Reference to an opened filehandle
2793# $_[1]: Either 0 or 1
2794# Returns: -1 on failure, the 0 on success.
2795sub i2c_smbus_write_quick
2796{
2797  my ($file,$value) = @_;
2798  my @data;
2799  i2c_smbus_access $file, $value, 0, SMBUS_QUICK, \@data
2800         or return -1;
2801  return 0;
2802}
2803
2804# $_[0]: Reference to an opened filehandle
2805# Returns: -1 on failure, the read byte on success.
2806sub i2c_smbus_read_byte
2807{
2808  my ($file) = @_;
2809  my @data;
2810  i2c_smbus_access $file, SMBUS_READ, 0, SMBUS_BYTE, \@data
2811         or return -1;
2812  return $data[0];
2813}
2814
2815# $_[0]: Reference to an opened filehandle
2816# $_[1]: Command byte (usually register number)
2817# Returns: -1 on failure, the read byte on success.
2818sub i2c_smbus_read_byte_data
2819{
2820  my ($file,$command) = @_;
2821  my @data;
2822  i2c_smbus_access $file, SMBUS_READ, $command, SMBUS_BYTE_DATA, \@data
2823         or return -1;
2824  return $data[0];
2825}
2826 
2827# $_[0]: Reference to an opened filehandle
2828# $_[1]: Command byte (usually register number)
2829# Returns: -1 on failure, the read word on success.
2830# Note: some devices use the wrong endiannes; use swap_bytes to correct for
2831# this.
2832sub i2c_smbus_read_word_data
2833{
2834  my ($file,$command) = @_;
2835  my @data;
2836  i2c_smbus_access $file, SMBUS_READ, $command, SMBUS_WORD_DATA, \@data
2837         or return -1;
2838  return $data[0] + 256 * $data[1];
2839}
2840
2841# $_[0]: Reference to an opened filehandle
2842# $_[1]: Address
2843# $_[2]: Functionalities of this i2c adapter
2844# Returns: 1 on successful probing, 0 else.
2845# This function is meant to prevent AT24RF08 corruption and write-only
2846# chips locks. This is done by choosing the best probing method depending
2847# on the address range.
2848sub i2c_probe($$$)
2849{
2850  my ($file, $addr, $funcs) = @_;
2851  my $data = [];
2852  if (($addr >= 0x50 && $addr <= 0x5F)
2853   || ($addr >= 0x30 && $addr <= 0x37)) {
2854    # This covers all EEPROMs we know of, including page protection addresses.
2855    # Note that some page protection addresses will not reveal themselves with
2856    # this, because they ack on write only, but this is probably better since
2857    # some EEPROMs write-protect themselves permanently on almost any write to
2858    # their page protection address.
2859    return 0 unless ($funcs & I2C_FUNC_SMBUS_READ_BYTE);
2860    return i2c_smbus_access($file, SMBUS_READ, 0, SMBUS_BYTE, $data);
2861  } else {
2862    return 0 unless ($funcs & I2C_FUNC_SMBUS_QUICK);
2863    return i2c_smbus_access($file, SMBUS_WRITE, 0, SMBUS_QUICK, $data);
2864  }
2865}
2866
2867####################
2868# ADAPTER SCANNING #
2869####################
2870
2871use vars qw(@chips_detected);
2872
2873# We will build a complicated structure @chips_detected here, being:
2874# A list of
2875#  references to hashes
2876#    with field 'driver', being a string with the driver name for this chip;
2877#    with field 'detected'
2878#      being a reference to a list of
2879#        references to hashes of type 'detect_data';
2880#    with field 'misdetected'
2881#      being a reference to a list of
2882#        references to hashes of type 'detect_data'
2883
2884# Type detect_data:
2885# A hash
2886#   with field 'i2c_adap' containing an adapter string as appearing
2887#        in /proc/bus/i2c (if this is an I2C detection)
2888#  with field 'i2c_devnr', contianing the /dev/i2c-* number of this
2889#       adapter (if this is an I2C detection)
2890#  with field 'i2c_driver', containing the driver name for this adapter
2891#       (if this is an I2C detection)
2892#  with field 'i2c_addr', containing the I2C address of the detection;
2893#       (if this is an I2C detection)
2894#  with field 'i2c_sub_addrs', containing a reference to a list of
2895#       other I2C addresses (if this is an I2C detection)
2896#  with field 'isa_addr' containing the ISA address this chip is on
2897#       (if this is an ISA detection)
2898#  with field 'conf', containing the confidence level of this detection
2899#  with field 'chipname', containing the chip name
2900
2901# This adds a detection to the above structure. We do no alias detection
2902# here; so you should do ISA detections *after* all I2C detections.
2903# Not all possibilities of i2c_addr and i2c_sub_addrs are exhausted.
2904# In all normal cases, it should be all right.
2905# $_[0]: chip driver
2906# $_[1]: reference to data hash
2907# Returns: Nothing
2908sub add_i2c_to_chips_detected
2909{
2910  my ($chipdriver,$datahash) = @_;
2911  my ($i,$new_detected_ref,$new_misdetected_ref,$detected_ref,$misdetected_ref,
2912      $main_entry,$detected_entry,$put_in_detected,@hash_addrs,@entry_addrs,
2913      $do_not_add);
2914
2915  # First determine where the hash has to be added.
2916  for ($i = 0; $i < @chips_detected; $i++) {
2917    last if ($chips_detected[$i]->{driver} eq $chipdriver);
2918  }
2919  if ($i == @chips_detected) {
2920    push @chips_detected, { driver => $chipdriver,
2921                            detected => [],
2922                            misdetected => [] };
2923  }
2924  $new_detected_ref = $chips_detected[$i]->{detected};
2925  $new_misdetected_ref = $chips_detected[$i]->{misdetected};
2926
2927  # Find out whether our new entry should go into the detected or the
2928  # misdetected list. We compare all i2c addresses; if at least one matches,
2929  # but our conf value is lower, we assume this is a misdetect.
2930  @hash_addrs = ($datahash->{i2c_addr});
2931  push @hash_addrs, @{$datahash->{i2c_sub_addrs}}
2932       if exists $datahash->{i2c_sub_addrs};
2933  $put_in_detected = 1;
2934  $do_not_add = 0;
2935  FIND_LOOP:
2936  foreach $main_entry (@chips_detected) {
2937    foreach $detected_entry (@{$main_entry->{detected}}) {
2938      @entry_addrs = ($detected_entry->{i2c_addr});
2939      push @entry_addrs, @{$detected_entry->{i2c_sub_addrs}}
2940               if exists $detected_entry->{i2c_sub_addrs};
2941      if ($detected_entry->{i2c_devnr} == $datahash->{i2c_devnr} and
2942          any_list_match \@entry_addrs, \@hash_addrs) {
2943        if ($detected_entry->{conf} >= $datahash->{conf}) {
2944          $put_in_detected = 0;
2945        }
2946        if ($chipdriver eq $main_entry->{driver}) {
2947          $do_not_add = 1;
2948        }
2949        last FIND_LOOP;
2950      }
2951    }
2952  }
2953
2954  if ($put_in_detected) {
2955    # Here, we move all entries from detected to misdetected which
2956    # match at least in one main or sub address. This may not be the
2957    # best idea to do, as it may remove detections without replacing
2958    # them with second-best ones. Too bad.
2959    # (Khali 2003-09-13) If the driver is the same, the "misdetected"
2960    # entry is simply deleted; failing to do so cause the configuration
2961    # lines generated later to look very confusing (the driver will
2962    # be told to ignore valid addresses).
2963    @hash_addrs = ($datahash->{i2c_addr});
2964    push @hash_addrs, @{$datahash->{i2c_sub_addrs}} 
2965         if exists $datahash->{i2c_sub_addrs};
2966    foreach $main_entry (@chips_detected) {
2967      $detected_ref = $main_entry->{detected};
2968      $misdetected_ref = $main_entry->{misdetected};
2969      for ($i = @$detected_ref-1; $i >=0; $i--) {
2970        @entry_addrs = ($detected_ref->[$i]->{i2c_addr});
2971        push @entry_addrs, @{$detected_ref->[$i]->{i2c_sub_addrs}}
2972             if exists $detected_ref->[$i]->{i2c_sub_addrs};
2973        if ($detected_ref->[$i]->{i2c_devnr} == $datahash->{i2c_devnr} and
2974            any_list_match \@entry_addrs, \@hash_addrs) {
2975          push @$misdetected_ref,$detected_ref->[$i]
2976            unless $chipdriver eq $main_entry->{driver};
2977          splice @$detected_ref, $i, 1;
2978        }
2979      }
2980    }
2981
2982    # Now add the new entry to detected
2983    push @$new_detected_ref, $datahash;
2984  } else {
2985    # No hard work here
2986    push @$new_misdetected_ref, $datahash
2987      unless $do_not_add;
2988  }
2989}
2990
2991# This adds a detection to the above structure. We also do alias detection
2992# here; so you should do ISA detections *after* all I2C detections.
2993# $_[0]: alias detection function
2994# $_[1]: chip driver
2995# $_[2]: reference to data hash
2996# Returns: 0 if it is not an alias, datahash reference if it is.
2997sub add_isa_to_chips_detected
2998{
2999  my ($alias_detect,$chipdriver,$datahash) = @_;
3000  my ($i,$new_detected_ref,$new_misdetected_ref,$detected_ref,$misdetected_ref,
3001      $main_entry,$isalias);
3002
3003  # First determine where the hash has to be added.
3004  $isalias=0;
3005  for ($i = 0; $i < @chips_detected; $i++) {
3006    last if ($chips_detected[$i]->{driver} eq $chipdriver);
3007  }
3008  if ($i == @chips_detected) {
3009    push @chips_detected, { driver => $chipdriver,
3010                            detected => [],
3011                            misdetected => [] };
3012  }
3013  $new_detected_ref = $chips_detected[$i]->{detected};
3014  $new_misdetected_ref = $chips_detected[$i]->{misdetected};
3015
3016  # Now, we are looking for aliases. An alias can only be the same chiptype.
3017  # If an alias is found in the misdetected list, we add the new information
3018  # and terminate this function. If it is found in the detected list, we
3019  # still have to check whether another chip has claimed this ISA address.
3020  # So we remove the old entry from the detected list and put it in datahash.
3021
3022  # Misdetected alias detection:
3023  for ($i = 0; $i < @$new_misdetected_ref; $i++) {
3024    if (exists $new_misdetected_ref->[$i]->{i2c_addr} and
3025        not exists $new_misdetected_ref->[$i]->{isa_addr} and
3026        defined $alias_detect and
3027        $new_misdetected_ref->[$i]->{chipname} eq $datahash->{chipname}) {
3028      open(local *FILE, "$dev_i2c$new_misdetected_ref->[$i]->{i2c_devnr}") or
3029        print("Can't open $dev_i2c$new_misdetected_ref->[$i]->{i2c_devnr}?!?\n"),
3030        next;
3031      binmode FILE;
3032      i2c_set_slave_addr \*FILE,$new_misdetected_ref->[$i]->{i2c_addr} or
3033           print("Can't set I2C address for ",
3034                 "$dev_i2c$new_misdetected_ref->[$i]->{i2c_devnr}?!?\n"),
3035           next;
3036      if (&$alias_detect ($datahash->{isa_addr},\*FILE,
3037                          $new_misdetected_ref->[$i]->{i2c_addr})) {
3038        $new_misdetected_ref->[$i]->{isa_addr} = $datahash->{isa_addr};
3039        return $new_misdetected_ref->[$i]; 
3040      }
3041    }
3042  }
3043
3044  # Detected alias detection:
3045  for ($i = 0; $i < @$new_detected_ref; $i++) {
3046    if (exists $new_detected_ref->[$i]->{i2c_addr} and
3047        not exists $new_detected_ref->[$i]->{isa_addr} and
3048        defined $alias_detect and
3049        $new_detected_ref->[$i]->{chipname} eq $datahash->{chipname}) {
3050      open(local *FILE, "$dev_i2c$new_detected_ref->[$i]->{i2c_devnr}") or
3051        print("Can't open $dev_i2c$new_detected_ref->[$i]->{i2c_devnr}?!?\n"),
3052        next;
3053      binmode FILE;
3054      i2c_set_slave_addr \*FILE,$new_detected_ref->[$i]->{i2c_addr} or
3055           print("Can't set I2C address for ",
3056                 "$dev_i2c$new_detected_ref->[$i]->{i2c_devnr}?!?\n"),
3057           next;
3058      if (&$alias_detect ($datahash->{isa_addr},\*FILE,
3059                          $new_detected_ref->[$i]->{i2c_addr})) {
3060        $new_detected_ref->[$i]->{isa_addr} = $datahash->{isa_addr};
3061        ($datahash) = splice (@$new_detected_ref, $i, 1);
3062        $isalias=1;
3063        last;
3064      }
3065    }
3066  }
3067
3068
3069  # Find out whether our new entry should go into the detected or the
3070  # misdetected list. We only compare main isa_addr here, of course.
3071  # (Khali 2004-05-12) If the driver is the same, the "misdetected"
3072  # entry is simply deleted; same we do for I2C chips.
3073  foreach $main_entry (@chips_detected) {
3074    $detected_ref = $main_entry->{detected};
3075    $misdetected_ref = $main_entry->{misdetected};
3076    for ($i = 0; $i < @{$main_entry->{detected}}; $i++) {
3077      if (exists $detected_ref->[$i]->{isa_addr} and
3078          exists $datahash->{isa_addr} and
3079          $detected_ref->[$i]->{isa_addr} == $datahash->{isa_addr}) {
3080        if ($detected_ref->[$i]->{conf} >= $datahash->{conf}) {
3081          push @$new_misdetected_ref, $datahash
3082            unless $main_entry->{driver} eq $chipdriver;
3083        } else {
3084          push @$misdetected_ref,$detected_ref->[$i]
3085            unless $main_entry->{driver} eq $chipdriver;
3086          splice @$detected_ref, $i,1;
3087          push @$new_detected_ref, $datahash;
3088        }
3089        if ($isalias) {
3090          return $datahash;
3091        } else {
3092          return 0;
3093        }
3094      }
3095    }
3096  }
3097
3098  # Not found? OK, put it in the detected list
3099  push @$new_detected_ref, $datahash;
3100  if ($isalias) {
3101    return $datahash;
3102  } else {
3103    return 0;
3104  }
3105}
3106
3107# From the list of known I2C/SMBus devices, build a list of I2C addresses
3108# which are worth probing. There's no point in probing an address for which
3109# we don't know a single device, and probing some addresses has caused
3110# random trouble in the past.
3111sub i2c_addresses_to_scan()
3112{
3113  my @used;
3114  my @addresses;
3115  my $addr;
3116
3117  foreach my $chip (@chip_ids) {
3118    next unless defined $chip->{'i2c_addrs'};
3119    next if $chip->{'driver'} eq 'not-a-sensor';
3120    foreach $addr (@{$chip->{'i2c_addrs'}}) {
3121      $used[$addr]++;
3122    }
3123  }
3124
3125  for ($addr = 0x03; $addr <= 0x77; $addr++) {
3126    push @addresses, $addr if $used[$addr];
3127  }
3128  return \@addresses;
3129}
3130
3131# $_[0]: The number of the adapter to scan
3132# $_[1]: The name of the adapter, as appearing in /proc/bus/i2c
3133# $_[2]: The driver of the adapter
3134# @_[3]: Addresses not to scan (array reference)
3135sub scan_adapter
3136{
3137  my ($adapter_nr, $adapter_name, $adapter_driver, $not_to_scan) = @_;
3138  my ($funcs, $chip, $addr, $conf, @chips, $new_hash, $other_addr);
3139
3140  # As we modify it, we need a copy
3141  my @not_to_scan = @$not_to_scan;
3142
3143  open(local *FILE, "$dev_i2c$adapter_nr") or 
3144    (print "Can't open $dev_i2c$adapter_nr\n"), return;
3145  binmode FILE;
3146
3147  # Can we probe this adapter?
3148  $funcs = i2c_get_funcs(\*FILE);
3149  if ($funcs < 0) {
3150    print "Adapter failed to provide its functionalities, skipping.\n";
3151    return;
3152  }
3153  if (!($funcs & (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_READ_BYTE))) {
3154    print "Adapter cannot be probed, skipping.\n";
3155    return;
3156  }
3157  if (~$funcs & (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_READ_BYTE)) {
3158    print "Adapter doesn't support all probing functions.\n",
3159          "Some addresses won't be probed.\n";
3160  }
3161
3162  # Now scan each address in turn
3163  foreach $addr (@{$i2c_addresses_to_scan}) {
3164    # As the not_to_scan list is sorted, we can check it fast
3165    if (@not_to_scan and $not_to_scan[0] == $addr) {
3166      shift @not_to_scan;
3167      next;
3168    }
3169
3170    if (!i2c_set_slave_addr(\*FILE, $addr)) {
3171      # If the address is busy, in Linux 2.6 we can find out which driver
3172      # is using it, and we assume it is the right one. In Linux 2.4 we
3173      # just give up and warn the user.
3174      my ($device, $driver);
3175      if (defined($sysfs_root)) {
3176        $device = sprintf("$sysfs_root/bus/i2c/devices/\%d-\%04x",
3177                             $adapter_nr, $addr);
3178        $driver = sysfs_device_driver($device);
3179      }
3180      if (defined($driver)) {
3181        $new_hash = {
3182          conf => 6, # Arbitrary confidence
3183          i2c_addr => $addr,
3184          chipname => sysfs_device_attribute($device, "name") || "unknown",
3185          i2c_adap => $adapter_name,
3186          i2c_driver => $adapter_driver,
3187          i2c_devnr => $adapter_nr,
3188        };
3189
3190        printf "Client found at address 0x\%02x\n", $addr;
3191        printf "Handled by driver `\%s' (already loaded), chip type `\%s'\n",
3192               $driver, $new_hash->{chipname};
3193
3194        # Only add it to the list if this is something we would have
3195        # detected, else we end up with random i2c chip drivers listed
3196        # (for example media/video drivers.)
3197        if (exists $modules_supported{$driver}) {
3198          add_i2c_to_chips_detected($driver, $new_hash);
3199        } else {
3200          print "    (note: this is probably NOT a sensor chip!)\n";
3201        }   
3202      } else {
3203        printf("Client at address 0x%02x can not be probed - ".
3204               "unload all client drivers first!\n", $addr);
3205      }
3206      next;
3207    }
3208
3209    next unless i2c_probe(\*FILE, $addr, $funcs);
3210    printf "Client found at address 0x%02x\n",$addr;
3211
3212    $| = 1;
3213    foreach $chip (@chip_ids) {
3214      if (exists $chip->{i2c_addrs} and contains $addr, @{$chip->{i2c_addrs}}) {
3215        printf("\%-60s", sprintf("Probing for `\%s'... ", $chip->{name}));
3216        if (($conf,@chips) = &{$chip->{i2c_detect}} (\*FILE ,$addr)) {
3217          if ($chip->{driver} eq "not-a-sensor") {
3218            print "Yes\n",
3219                  "    (confidence $conf, not a hardware monitoring chip";
3220          } else {
3221            print "Success!\n",
3222                  "    (confidence $conf, driver `$chip->{driver}'";
3223          }
3224          if (@chips) {
3225            print ", other addresses:";
3226            @chips = sort @chips;
3227            foreach $other_addr (@chips) {
3228              printf(" 0x%02x",$other_addr);
3229            }
3230          }
3231          printf ")\n";
3232
3233          next if ($chip->{driver} eq "not-a-sensor"
3234                || $chip->{driver} eq "use-isa-instead");
3235
3236          $new_hash = { conf => $conf,
3237                        i2c_addr => $addr,
3238                        chipname => $chip->{name},
3239                        i2c_adap => $adapter_name,
3240                        i2c_driver => $adapter_driver,
3241                        i2c_devnr => $adapter_nr,
3242                      };
3243          if (@chips) {
3244            my @chips_copy = @chips;
3245            $new_hash->{i2c_sub_addrs} = \@chips_copy;
3246          }
3247          add_i2c_to_chips_detected $chip->{driver}, $new_hash;
3248        } else {
3249          print "No\n";
3250        }
3251      }
3252    }
3253    $| = 0;
3254  }
3255}
3256
3257sub scan_isa_bus
3258{
3259  my ($chip,$addr,$conf);
3260  $| = 1;
3261  foreach $chip (@chip_ids) {
3262    next if not exists $chip->{isa_addrs} or not exists $chip->{isa_detect};
3263    foreach $addr (@{$chip->{isa_addrs}}) {
3264      printf("\%-60s", sprintf("Probing for `\%s'\ at 0x\%x... ", $chip->{name},
3265                               $addr));
3266      $conf = &{$chip->{isa_detect}} ($addr);
3267      print("No\n"), next if not defined $conf;
3268      print "Success!\n";
3269      printf "    (confidence %d, driver `%s')\n", $conf, $chip->{driver};
3270      my $new_hash = { conf => $conf,
3271                       isa_addr => $addr,
3272                       chipname => $chip->{name}
3273                     };
3274      $new_hash = add_isa_to_chips_detected $chip->{alias_detect},$chip->{driver},
3275                                            $new_hash;
3276      if ($new_hash) {
3277        printf "    Alias of the chip on I2C bus `%s', address 0x%04x\n",
3278                        $new_hash->{i2c_adap},$new_hash->{i2c_addr};
3279      }
3280    }
3281  }
3282  $| = 0;
3283}
3284
3285use vars qw(%superio);
3286
3287# The following are taken from the PNP ISA spec (so it's supposed
3288# to be common to all Super I/O chips):
3289#  devidreg: The device ID register(s)
3290#  logdevreg: The logical device register
3291#  actreg: The activation register within the logical device
3292#  actmask: The activation bit in the activation register
3293#  basereg: The I/O base register within the logical device
3294%superio = (
3295  devidreg => 0x20,
3296  logdevreg => 0x07,
3297  actreg => 0x30,
3298  actmask => 0x01,
3299  basereg => 0x60,
3300);
3301
3302sub exit_superio
3303{
3304  my ($addrreg, $datareg) = @_;
3305
3306  # Some chips (SMSC, Winbond) want this
3307  outb($addrreg, 0xaa);
3308
3309  # Return to "Wait For Key" state (PNP-ISA spec)
3310  outb($addrreg, 0x02);
3311  outb($datareg, 0x02);
3312}
3313
3314# Guess if an unknown Super-I/O chip has sensors
3315sub guess_superio_ld($$$)
3316{
3317  my ($addrreg, $datareg, $typical_addr) = @_;
3318  my ($oldldn, $ldn, $addr);
3319
3320  # Save logical device number
3321  outb($addrreg, $superio{logdevreg});
3322  $oldldn = inb($datareg);
3323
3324  for ($ldn = 0; $ldn < 16; $ldn++) {
3325    # Select logical device
3326    outb($addrreg, $superio{logdevreg});
3327    outb($datareg, $ldn);
3328
3329    # Read base I/O address
3330    outb($addrreg, $superio{basereg});
3331    $addr = inb($datareg) << 8;
3332    outb($addrreg, $superio{basereg} + 1);
3333    $addr |= inb($datareg);
3334    next unless ($addr & 0xfff8) == $typical_addr;
3335
3336    printf "    (logical device \%X has address 0x\%x, could be sensors)\n",
3337           $ldn, $addr;
3338    last;
3339  }
3340
3341  # Be nice, restore original logical device
3342  outb($addrreg, $superio{logdevreg});
3343  outb($datareg, $oldldn);
3344}
3345
3346sub probe_superio($$$)
3347{
3348  my ($addrreg, $datareg, $chip) = @_;
3349  my ($val, $addr);
3350
3351  printf "\%-60s",  "Found `$chip->{name}'";
3352
3353  # Does it have hardware monitoring capabilities?
3354  if (!exists $chip->{driver}) {
3355    print "\n    (no information available)\n";
3356    return;
3357  }
3358  if ($chip->{driver} eq "not-a-sensor") {
3359    print "\n    (no hardware monitoring capabilities)\n";
3360    return;
3361  }
3362  if ($chip->{driver} eq "via-smbus-only") {
3363    print "\n    (hardware monitoring capabilities accessible via SMBus only)\n";
3364    return;
3365  }
3366
3367  # Switch to the sensor logical device
3368  outb($addrreg, $superio{logdevreg});
3369  outb($datareg, $chip->{logdev});
3370
3371  # Check the activation register
3372  outb($addrreg, $superio{actreg});
3373  $val = inb($datareg);
3374  if (!($val & $superio{actmask})) {
3375    print "\n    (but not activated)\n";
3376    return;
3377  }
3378
3379  # Get the IO base register
3380  outb($addrreg, $superio{basereg});
3381  $addr = inb($datareg);
3382  outb($addrreg, $superio{basereg} + 1);
3383  $addr = ($addr << 8) | inb($datareg);
3384  if ($addr == 0) {
3385    print "\n    (but no address specified)\n";
3386    return;
3387  }
3388  print "Success!\n";
3389  printf "    (address 0x\%x, driver `%s')\n", $addr, $chip->{driver};
3390  my $new_hash = { conf => 9,
3391                   isa_addr => $addr,
3392                   chipname => $chip->{name}
3393                 };
3394  add_isa_to_chips_detected $chip->{alias_detect},$chip->{driver},
3395                                        $new_hash;
3396}
3397
3398# Detection routine for non-standard SMSC Super I/O chips
3399# $_[0]: Super I/O LPC config/index port
3400# $_[1]: Super I/O LPC data port
3401# $_[2]: Reference to array of non-standard chips
3402# Return values: 1 if non-standard chip found, 0 otherwise
3403sub smsc_ns_detect_superio
3404{
3405    my ($addrreg, $datareg, $ns_chips) = @_;
3406    my ($val, $chip);
3407
3408    # read alternate device ID register
3409    outb($addrreg, 0x0d);
3410    $val = inb($datareg);
3411    if ($val == 0x00 || $val == 0xff) {
3412        return 0;
3413    }
3414
3415    print "Yes\n";
3416
3417    foreach $chip (@{$ns_chips}) {
3418        if ($chip->{devid} == $val) {
3419            probe_superio($addrreg, $datareg, $chip);
3420            return 1;
3421        }
3422    }
3423
3424    printf("Found unknown non-standard chip with ID 0x%02x\n", $val);
3425    return 1;
3426}
3427
3428sub scan_superio
3429{
3430  my ($addrreg, $datareg) = @_;
3431  my ($val, $found);
3432
3433  printf("Probing for Super-I/O at 0x\%x/0x\%x\n", $addrreg, $datareg);
3434
3435  $| = 1;
3436# reset state to avoid false positives
3437  exit_superio($addrreg, $datareg);
3438  FAMILY:
3439  foreach my $family (@superio_ids) {
3440    printf("\%-60s", "Trying family `$family->{family}'... ");
3441# write the password
3442    foreach $val (@{$family->{enter}->{$addrreg}}) {
3443      outb($addrreg, $val);
3444    }
3445# call the non-standard detection routine first if it exists
3446    if (defined($family->{ns_detect}) && 
3447        &{$family->{ns_detect}}($addrreg, $datareg, $family->{ns_chips})) {
3448      exit_superio($addrreg, $datareg);
3449      last FAMILY;
3450    }
3451# did it work?
3452    outb($addrreg, $superio{devidreg});
3453    $val = inb($datareg);
3454    outb($addrreg, $superio{devidreg} + 1);
3455    $val = ($val << 8) | inb($datareg);
3456    if ($val == 0x0000 || $val == 0xffff) {
3457      print "No\n";
3458      next FAMILY;
3459    }
3460    print "Yes\n";
3461
3462    $found = 0;
3463    foreach my $chip (@{$family->{chips}}) {
3464      if (($chip->{devid} > 0xff && ($val & ($chip->{devid_mask} || 0xffff)) == $chip->{devid})
3465       || ($chip->{devid} <= 0xff && ($val >> 8) == $chip->{devid})) {
3466        probe_superio($addrreg, $datareg, $chip);
3467        $found++;
3468      }
3469    }
3470
3471    if (!$found) {
3472      printf("Found unknown chip with ID 0x%04x\n", $val);
3473      # Guess if a logical device could correspond to sensors
3474      guess_superio_ld($addrreg, $datareg, $family->{guess})
3475        if defined $family->{guess};
3476    }
3477
3478    exit_superio($addrreg, $datareg);
3479    last FAMILY;
3480  }
3481  $| = 0;
3482}
3483
3484
3485sub scan_cpu($)
3486{
3487  my $entry = shift;
3488  my $confidence;
3489
3490  printf("\%-60s", "$entry->{name}... ");
3491  if (defined ($confidence = $entry->{detect}())) {
3492    print "Success!\n";
3493    printf "    (driver `%s')\n", $entry->{driver};
3494    my $new_hash = {
3495      conf => $confidence,
3496      chipname => $entry->{name},
3497    };
3498    add_isa_to_chips_detected(undef, $entry->{driver}, $new_hash);
3499  } else {
3500    print "No\n";
3501  }
3502}
3503
3504
3505##################
3506# CHIP DETECTION #
3507##################
3508
3509# This routine allows you to select which chips are optionally added to the
3510# chip detection list. The most common use is to allow for different chip
3511# detection/drivers based on different linux kernels
3512# This routine follows the pattern of the SiS adapter special cases
3513sub chip_special_cases
3514{
3515        # Based on the kernel, add the appropriate chip structures to the
3516        # chip_ids detection list
3517        if (kernel_version_at_least(2, 6, 24)) {
3518                push @chip_ids, @chip_fschmd_ids;
3519        } else {
3520                push @chip_ids, @chip_oldfsc_ids;
3521        }
3522
3523        if (kernel_version_at_least(2, 6, 0)) {
3524                push @chip_ids, @chip_kern26_ids;
3525        } else {
3526                push @chip_ids, @chip_kern24_ids;
3527        }
3528}
3529
3530# Each function returns a confidence value. The higher this value, the more
3531# sure we are about this chip. A Winbond W83781D, for example, will be
3532# detected as a LM78 too; but as the Winbond detection has a higher confidence
3533# factor, you should identify it as a Winbond.
3534
3535# Each function returns a list. The first element is the confidence value;
3536# Each element after it is an SMBus address. In this way, we can detect
3537# chips with several SMBus addresses. The SMBus address for which the
3538# function was called is never returned.
3539
3540# If there are devices which get confused if they are only read from, then
3541# this program will surely confuse them. But we guarantee never to write to
3542# any of these devices.
3543
3544
3545# $_[0]: A reference to the file descriptor to access this chip.
3546# $_[1]: Address
3547# Returns: undef if not detected, (7) if detected.
3548# Registers used: 0x58
3549sub mtp008_detect
3550{
3551  my ($file,$addr) = @_;
3552  return if (i2c_smbus_read_byte_data($file,0x58)) != 0xac;
3553  return (8);
3554}
3555 
3556# $_[0]: Chip to detect (0 = LM78, 1 = LM78-J, 2 = LM79)
3557# $_[1]: A reference to the file descriptor to access this chip.
3558# $_[2]: Address
3559# Returns: undef if not detected, (6) if detected.
3560# Registers used:
3561#   0x40: Configuration
3562#   0x48: Full I2C Address
3563#   0x49: Device ID
3564sub lm78_detect
3565{
3566  my $reg;
3567  my ($chip,$file,$addr) = @_;
3568  return unless i2c_smbus_read_byte_data($file,0x48) == $addr;
3569  return unless (i2c_smbus_read_byte_data($file,0x40) & 0x80) == 0x00;
3570  $reg = i2c_smbus_read_byte_data($file,0x49);
3571  return unless ($chip == 0 and ($reg == 0x00 or $reg == 0x20)) or
3572                    ($chip == 1 and $reg == 0x40) or
3573                    ($chip == 2 and ($reg & 0xfe) == 0xc0);
3574  return (6);
3575}
3576
3577# $_[0]: Chip to detect (0 = LM78, 1 = LM78-J, 2 = LM79)
3578# $_[1]: Address
3579# Returns: undef if not detected, 6 if detected.
3580# Note: Only address 0x290 is scanned at this moment.
3581sub lm78_isa_detect
3582{
3583  my ($chip,$addr) = @_ ;
3584  my $val = inb ($addr + 1);
3585  return if inb ($addr + 2) != $val or inb ($addr + 3) != $val or 
3586            inb ($addr + 7) != $val;
3587
3588  $val = inb($addr + 5);
3589  outb($addr + 5, ~$val & 0x7f);
3590  if ((inb ($addr+5) & 0x7f) != (~ $val & 0x7f)) {
3591    outb($addr+5,$val);
3592    return;
3593  }
3594  my $readproc = sub { isa_read_byte $addr + 5, $addr + 6, @_ };
3595  return unless (&$readproc(0x40) & 0x80) == 0x00;
3596  my $reg = &$readproc(0x49);
3597  return unless ($chip == 0 and ($reg == 0x00 or $reg == 0x20)) or
3598                ($chip == 1 and $reg == 0x40) or
3599                ($chip == 2 and ($reg & 0xfe) == 0xc0);
3600
3601  # Explicitly prevent misdetection of Winbond chips
3602  $reg = &$readproc(0x4f);
3603  return if $reg == 0xa3 || $reg == 0x5c;
3604
3605  # Explicitly prevent misdetection of ITE chips
3606  $reg = &$readproc(0x58);
3607  return if $reg == 0x90;
3608
3609  return 6;
3610}
3611
3612
3613# $_[0]: Chip to detect (0 = LM78, 1 = LM78-J, 2 = LM79)
3614# $_[1]: ISA address
3615# $_[2]: I2C file handle
3616# $_[3]: I2C address
3617sub lm78_alias_detect
3618{
3619  my ($chip,$isa_addr,$file,$i2c_addr) = @_;
3620  my $i;
3621  my $readproc = sub { isa_read_byte $isa_addr + 5, $isa_addr + 6, @_ };
3622  return 0 unless &$readproc(0x48) == $i2c_addr;
3623  for ($i = 0x2b; $i <= 0x3d; $i ++) {
3624    return 0 unless &$readproc($i) == i2c_smbus_read_byte_data($file,$i);
3625  }
3626  return 1;
3627}
3628
3629# $_[0]: Chip to detect (0 = LM75, 1 = DS75)
3630# $_[1]: A reference to the file descriptor to access this chip.
3631# $_[2]: Address (unused)
3632# Returns: undef if not detected, 3 or 6 if detected;
3633#   6 means that the temperatures make sense;
3634#   3 means that the temperatures look strange;
3635# Registers used:
3636#   0x00: Temperature
3637#   0x01: Configuration
3638#   0x02: Hysteresis
3639#   0x03: Overtemperature Shutdown
3640#   0x04-0x07: No registers
3641# The first detection step is based on the fact that the LM75 has only
3642# four registers, and cycles addresses over 8-byte boundaries. We use the
3643# 0x04-0x07 addresses (unused) to improve the reliability. These are not
3644# real registers and will always return the last returned value. This isn't
3645# documented.
3646# Note that register 0x00 may change, so we can't use the modulo trick on it.
3647# The DS75 is a bit different, it doesn't cycle over 8-byte boundaries, and
3648# all register addresses from 0x04 to 0x0f behave like 0x04-0x07 do for
3649# the LM75.
3650sub lm75_detect
3651{
3652  my $i;
3653  my ($chip, $file, $addr) = @_;
3654  my $cur = i2c_smbus_read_word_data($file,0x00);
3655  my $conf = i2c_smbus_read_byte_data($file,0x01);
3656
3657  my $hyst = i2c_smbus_read_word_data($file,0x02);
3658  my $maxreg = $chip == 1 ? 0x0f : 0x07;
3659  for $i (0x04 .. $maxreg) {
3660    return if i2c_smbus_read_word_data($file, $i) != $hyst;
3661  }
3662
3663  my $os = i2c_smbus_read_word_data($file,0x03);
3664  for $i (0x04 .. $maxreg) {
3665    return if i2c_smbus_read_word_data($file, $i) != $os;
3666  }
3667
3668  if ($chip == 0) {
3669    for ($i = 8; $i <= 248; $i += 40) {
3670      return if i2c_smbus_read_byte_data($file, $i + 0x01) != $conf
3671             or i2c_smbus_read_word_data($file, $i + 0x02) != $hyst
3672             or i2c_smbus_read_word_data($file, $i + 0x03) != $os;
3673    }
3674  }
3675
3676  # All registers hold the same value, obviously a misdetection
3677  return if $conf == ($cur & 0xff) and $cur == $hyst
3678    and $cur == $os;
3679
3680  $cur = swap_bytes($cur);
3681  $hyst = swap_bytes($hyst);
3682  $os = swap_bytes($os);
3683  # Unused bits
3684  return if $chip == 0 and ($conf & 0xe0);
3685  return if $chip == 1 and ($conf & 0x80);
3686
3687  $cur = $cur >> 8;
3688  $hyst = $hyst >> 8;
3689  $os = $os >> 8;
3690  # Most probable value ranges
3691  return 6 if $cur <= 100 and ($hyst >= 10 && $hyst <= 125)
3692    and ($os >= 20 && $os <= 127) and $hyst < $os;
3693  return 3;
3694}
3695
3696# $_[0]: A reference to the file descriptor to access this chip.
3697# $_[1]: Address
3698# Returns: undef if not detected, 3 or 6 if detected;
3699#   6 means that the temperatures make sense;
3700#   3 means that the temperatures look strange;
3701# Registers used:
3702#   0x00: Temperature
3703#   0x01: Configuration
3704#   0x02: Hysteresis
3705#   0x03: Overtemperature Shutdown
3706#   0x04: Low limit
3707#   0x05: High limit
3708#   0x04-0x07: No registers
3709# The first detection step is based on the fact that the LM77 has only
3710# six registers, and cycles addresses over 8-byte boundaries. We use the
3711# 0x06-0x07 addresses (unused) to improve the reliability. These are not
3712# real registers and will always return the last returned value. This isn't
3713# documented.
3714# Note that register 0x00 may change, so we can't use the modulo trick on it.
3715sub lm77_detect
3716{
3717  my $i;
3718  my ($file,$addr) = @_;
3719  my $cur = i2c_smbus_read_word_data($file,0x00);
3720  my $conf = i2c_smbus_read_byte_data($file,0x01);
3721  my $hyst = i2c_smbus_read_word_data($file,0x02);
3722  my $os = i2c_smbus_read_word_data($file,0x03);
3723
3724  my $low = i2c_smbus_read_word_data($file,0x04);
3725  return if i2c_smbus_read_word_data($file,0x06) != $low;
3726  return if i2c_smbus_read_word_data($file,0x07) != $low;
3727
3728  my $high = i2c_smbus_read_word_data($file,0x05);
3729  return if i2c_smbus_read_word_data($file,0x06) != $high;
3730  return if i2c_smbus_read_word_data($file,0x07) != $high;
3731
3732  for ($i = 8; $i <= 248; $i += 40) {
3733    return if i2c_smbus_read_byte_data($file, $i + 0x01) != $conf;
3734    return if i2c_smbus_read_word_data($file, $i + 0x02) != $hyst;
3735    return if i2c_smbus_read_word_data($file, $i + 0x03) != $os;
3736    return if i2c_smbus_read_word_data($file, $i + 0x04) != $low;
3737    return if i2c_smbus_read_word_data($file, $i + 0x05) != $high;
3738  }
3739
3740  # All registers hold the same value, obviously a misdetection
3741  return if $conf == ($cur & 0xff) and $cur == $hyst
3742    and $cur == $os and $cur == $low and $cur == $high;
3743
3744  $cur = swap_bytes($cur);
3745  $os = swap_bytes($os);
3746  $hyst = swap_bytes($hyst);
3747  $low = swap_bytes($low);
3748  $high = swap_bytes($high);
3749  # Unused bits
3750  return if ($conf & 0xe0)
3751    or (($cur >> 12) != 0 && ($cur >> 12) != 0xf)
3752    or (($hyst >> 12) != 0 && ($hyst >> 12) != 0xf)
3753    or (($os >> 12) != 0 && ($os >> 12) != 0xf)
3754    or (($low >> 12) != 0 && ($low >> 12) != 0xf)
3755    or (($high >> 12) != 0 && ($high >> 12) != 0xf);
3756
3757  $cur /= 16;
3758  $hyst /= 16;
3759  $os /= 16;
3760  $high /= 16;
3761  $low /= 16;
3762
3763  # Most probable value ranges
3764  return 6 if $cur <= 100 and $hyst <= 40
3765    and ($os >= 20 && $os <= 127) and ($high >= 20 && $high <= 127);
3766  return 3;
3767}
3768
3769# $_[0]: Chip to detect (0 = LM92, 1 = LM76, 2 = MAX6633/MAX6634/MAX6635)
3770# $_[1]: A reference to the file descriptor to access this chip.
3771# $_[2]: Address
3772# Returns: undef if not detected, 2 or 4 if detected;
3773# Registers used:
3774#   0x01: Configuration (National Semiconductor only)
3775#   0x02: Hysteresis
3776#   0x03: Critical Temp
3777#   0x04: Low Limit
3778#   0x05: High Limit
3779#   0x07: Manufacturer ID (LM92 only)
3780# One detection step is based on the fact that the LM92 and clones have a
3781# limited number of registers, which cycle modulo 16 address values.
3782# Note that register 0x00 may change, so we can't use the modulo trick on it.
3783sub lm92_detect
3784{
3785  my ($chip, $file, $addr) = @_;
3786
3787  my $conf = i2c_smbus_read_byte_data($file, 0x01);
3788  my $hyst = i2c_smbus_read_word_data($file, 0x02);
3789  my $crit = i2c_smbus_read_word_data($file, 0x03);
3790  my $low = i2c_smbus_read_word_data($file, 0x04);
3791  my $high = i2c_smbus_read_word_data($file, 0x05);
3792
3793  return if $conf == 0 and $hyst == 0 and $crit == 0
3794        and $low == 0 and $high == 0;
3795
3796  return if $chip == 0
3797        and i2c_smbus_read_word_data($file, 0x07) != 0x0180;
3798 
3799  return if ($chip == 0 || $chip == 1)
3800        and ($conf & 0xE0);
3801
3802  for (my $i = 0; $i < 8; $i++) {
3803    return if i2c_smbus_read_byte_data($file, $i*16+0x01) != $conf;
3804    return if i2c_smbus_read_word_data($file, $i*16+0x02) != $hyst;
3805    return if i2c_smbus_read_word_data($file, $i*16+0x03) != $crit;
3806    return if i2c_smbus_read_word_data($file, $i*16+0x04) != $low;
3807    return if i2c_smbus_read_word_data($file, $i*16+0x05) != $high;
3808  }
3809 
3810  foreach my $temp ($hyst, $crit, $low, $high) {
3811    return if $chip == 2 and ($temp & 0x7F00);
3812    return if $chip != 2 and ($temp & 0x0700);
3813  }
3814
3815  return 4 if $chip == 0;
3816  return 2;
3817}
3818 
3819# $_[0]: A reference to the file descriptor to access this chip.
3820# $_[1]: Address
3821# Returns: undef if not detected, 3 if detected
3822# Registers used:
3823#   0xAA: Temperature
3824#   0xA1: High limit
3825#   0xA2: Low limit
3826#   0xAC: Configuration
3827# Detection is weak. We check if bit 4 (NVB) is clear, because it is
3828# unlikely to be set (would mean that EEPROM is currently being accessed).
3829# Temperature checkings will hopefully prevent LM75 or other chips from
3830# being detected as a DS1621.
3831sub ds1621_detect
3832{
3833  my $i;
3834  my ($file,$addr) = @_;
3835  my $temp = i2c_smbus_read_word_data($file,0xAA);
3836  my $high = i2c_smbus_read_word_data($file,0xA1);
3837  my $low = i2c_smbus_read_word_data($file,0xA2);
3838  return if ($temp | $high | $low) & 0x7F00;
3839  my $conf = i2c_smbus_read_byte_data($file,0xAC);
3840  return if ($temp == 0 && $high == 0 && $low == 0 && $conf == 0);
3841  return 3 if ($conf & 0x10) == 0x00;
3842  return;
3843}
3844
3845# $_[0]: A reference to the file descriptor to access this chip.
3846# $_[1]: Address
3847# Returns: undef if not detected, 1 to 3 if detected.
3848# Registers used:
3849#   0x00: Configuration register
3850#   0x02: Interrupt state register
3851#   0x2a-0x3d: Limits registers
3852# This one is easily misdetected since it doesn't provide identification
3853# registers. So we have to use some tricks:
3854#   - 6-bit addressing, so limits readings modulo 0x40 should be unchanged
3855#   - positive temperature limits
3856#   - limits order correctness
3857# Hopefully this should limit the rate of false positives, without increasing
3858# the rate of false negatives.
3859# Thanks to Lennard Klein for testing on a non-LM80 chip, which was
3860# previously misdetected, and isn't anymore. For reference, it scored
3861# a final confidence of 0, and changing from strict limit comparisons
3862# to loose comparisons did not change the score.
3863sub lm80_detect
3864{
3865  my ($i,$reg);
3866  my ($file,$addr) = @_;
3867
3868  return if (i2c_smbus_read_byte_data($file,0x00) & 0x80) != 0;
3869  return if (i2c_smbus_read_byte_data($file,0x02) & 0xc0) != 0;
3870
3871  for ($i = 0x2a; $i <= 0x3d; $i++) {
3872    $reg = i2c_smbus_read_byte_data($file,$i);
3873    return if i2c_smbus_read_byte_data($file,$i+0x40) != $reg;
3874    return if i2c_smbus_read_byte_data($file,$i+0x80) != $reg;
3875    return if i2c_smbus_read_byte_data($file,$i+0xc0) != $reg;
3876  }
3877 
3878  # Refine a bit by checking wether limits are in the correct order
3879  # (min<max for voltages, hyst<max for temperature). Since it is still
3880  # possible that the chip is an LM80 with limits not properly set,
3881  # a few "errors" are tolerated.
3882  my $confidence = 0;
3883  for ($i = 0x2a; $i <= 0x3a; $i++) {
3884    $confidence++
3885      if i2c_smbus_read_byte_data($file,$i) < i2c_smbus_read_byte_data($file,$i+1);
3886  }
3887  # hot temp<OS temp
3888  $confidence++
3889    if i2c_smbus_read_byte_data($file,0x38) < i2c_smbus_read_byte_data($file,0x3a);
3890
3891  # Negative temperature limits are unlikely.
3892  for ($i = 0x3a; $i <= 0x3d; $i++) {
3893    $confidence++ if (i2c_smbus_read_byte_data($file,$i) & 0x80) == 0;
3894  }
3895
3896  # $confidence is between 0 and 14
3897  $confidence = ($confidence >> 1) - 4;
3898  # $confidence is now between -4 and 3
3899
3900  return unless $confidence > 0;
3901
3902  return $confidence;
3903}
3904
3905# $_[0]: Chip to detect
3906#   (0 = LM82/LM83)
3907# $_[1]: A reference to the file descriptor to access this chip.
3908# $_[2]: Address
3909# Returns: undef if not detected, 4 to 8 if detected.
3910# Registers used:
3911#   0x02: Status 1
3912#   0x03: Configuration
3913#   0x04: Company ID of LM84
3914#   0x35: Status 2
3915#   0xfe: Manufacturer ID
3916#   0xff: Chip ID / die revision
3917# We can use the LM84 Company ID register because the LM83 and the LM82 are
3918# compatible with the LM84.
3919# The LM83 chip ID is missing from the datasheet and was contributed by
3920# Magnus Forsstrom: 0x03.
3921# At least some revisions of the LM82 seem to be repackaged LM83, so they
3922# have the same chip ID, and temp2/temp4 will be stuck in "OPEN" state.
3923# For this reason, we don't even try to distinguish between both chips.
3924# Thanks to Ben Gardner for reporting.
3925sub lm83_detect
3926{
3927  my ($chip, $file) = @_;
3928  return if i2c_smbus_read_byte_data($file,0xfe) != 0x01;
3929  my $chipid = i2c_smbus_read_byte_data($file,0xff);
3930  return if $chipid != 0x01 && $chipid != 0x03;
3931
3932  my $confidence = 4;
3933  $confidence++
3934    if (i2c_smbus_read_byte_data($file,0x02) & 0xa8) == 0x00;
3935  $confidence++
3936    if (i2c_smbus_read_byte_data($file,0x03) & 0x41) == 0x00;
3937  $confidence++
3938    if i2c_smbus_read_byte_data($file,0x04) == 0x00;
3939  $confidence++
3940    if (i2c_smbus_read_byte_data($file,0x35) & 0x48) == 0x00;
3941
3942  return $confidence;
3943}
3944
3945# $_[0]: Chip to detect
3946#   (0 = LM90, 1=LM89/LM99, 2=LM86, 3=ADM1032, 4=MAX6657/MAX6658/MAX6659,
3947#    5 = ADT7461, 6 = MAX6648/MAX6692, 7 = MAX6680/MAX6681,
3948#    8 = W83L771W/G), 9 = TI TMP401
3949# $_[1]: A reference to the file descriptor to access this chip.
3950# $_[2]: Address
3951# Returns: undef if not detected, 4, 6 or 8 if detected.
3952#   The Maxim chips MAX6657, MAX6658 and MAX6659 have a low confidence
3953#   value (4) because they don't have a die revision register.
3954# Registers used:
3955#   0x03: Configuration
3956#   0x04: Conversion rate
3957#   0xfe: Manufacturer ID
3958#   0xff: Chip ID / die revision
3959sub lm90_detect
3960{
3961  my ($chip, $file, $addr) = @_;
3962  my $mid = i2c_smbus_read_byte_data($file, 0xfe);
3963  my $cid = i2c_smbus_read_byte_data($file, 0xff);
3964  my $conf = i2c_smbus_read_byte_data($file, 0x03);
3965  my $rate = i2c_smbus_read_byte_data($file, 0x04);
3966
3967  if ($chip == 0) {
3968    return if ($conf & 0x2a) != 0;
3969    return if $rate > 0x09;
3970    return if $mid != 0x01;     # National Semiconductor
3971    return 8 if $cid == 0x21;   # LM90
3972    return 6 if ($cid & 0x0f) == 0x20;
3973  }
3974  if ($chip == 1) {
3975    return if ($conf & 0x2a) != 0;
3976    return if $rate > 0x09;
3977    return if $mid != 0x01;     # National Semiconductor
3978    return 8 if $addr == 0x4c and $cid == 0x31; # LM89/LM99
3979    return 8 if $addr == 0x4d and $cid == 0x34; # LM89-1/LM99-1
3980    return 6 if ($cid & 0x0f) == 0x30;
3981  }
3982  if ($chip == 2) {
3983    return if ($conf & 0x2a) != 0;
3984    return if $rate > 0x09;
3985    return if $mid != 0x01;     # National Semiconductor
3986    return 8 if $cid == 0x11;   # LM86
3987    return 6 if ($cid & 0xf0) == 0x10;
3988  }
3989  if ($chip == 3) {
3990    return if ($conf & 0x3f) != 0;
3991    return if $rate > 0x0a;
3992    return if $mid != 0x41;     # Analog Devices
3993    return 8 if ($cid & 0xf0) == 0x40; # ADM1032
3994  }
3995  if ($chip == 4) {
3996    return if ($conf & 0x1f) != ($mid & 0x0f); # No low nibble,
3997                                               # returns previous low nibble
3998    return if $rate > 0x09;
3999    return if $mid != 0x4d;     # Maxim
4000    return if $cid != 0x4d;     # No register, returns previous value
4001    return 4;
4002  }
4003  if ($chip == 5) {
4004    return if ($conf & 0x1b) != 0;
4005    return if $rate > 0x0a;
4006    return if $mid != 0x41;     # Analog Devices
4007    return 8 if $cid == 0x61;   # ADT7461
4008  }
4009  if ($chip == 6) {
4010    return if ($conf & 0x3f) != 0;
4011    return if $rate > 0x07;
4012    return if $mid != 0x4d;     # Maxim
4013    return if $cid != 0x59;     # MAX6648/MAX6692
4014    return 8;
4015  }   
4016  if ($chip == 7) {
4017    return if ($conf & 0x03) != 0;
4018    return if $rate > 0x07;
4019    return if $mid != 0x4d;     # Maxim
4020    return if $cid != 0x01;     # MAX6680/MAX6681
4021    return 6;
4022  }
4023  if ($chip == 8) {
4024    return if ($conf & 0x2a) != 0;
4025    return if $rate > 0x09;
4026    return if $mid != 0x5c;     # Winbond
4027    return if $cid != 0x00;     # W83L771W/G
4028    return 6;
4029  }
4030  if ($chip == 9) {
4031    return if ($conf & 0x1B) != 0;
4032    return if $rate > 0x0F;
4033    return if $mid != 0x55;     # Texas Instruments
4034    return if $cid != 0x11;     # TMP401
4035    return 6;
4036  }
4037  return;
4038}
4039
4040# $_[0]: Chip to detect
4041#   (1 = LM63, 2 = F75363SG)
4042# $_[1]: A reference to the file descriptor to access this chip.
4043# $_[2]: Address (unused)
4044# Returns: undef if not detected, 8 if detected.
4045# Registers used:
4046#   0xfe: Manufacturer ID
4047#   0xff: Chip ID / die revision
4048#   0x03: Configuration (two or three unused bits)
4049#   0x16: Alert mask (two or three unused bits)
4050#   0x03-0x0e: Mirrored registers (five pairs)
4051sub lm63_detect
4052{
4053  my ($chip, $file, $addr) = @_;
4054
4055  my $mid = i2c_smbus_read_byte_data($file, 0xfe);
4056  my $cid = i2c_smbus_read_byte_data($file, 0xff);
4057  my $conf = i2c_smbus_read_byte_data($file, 0x03);
4058  my $mask = i2c_smbus_read_byte_data($file, 0x16);
4059
4060  if ($chip == 1) {
4061    return if $mid != 0x01    # National Semiconductor
4062           || $cid != 0x41;   # LM63
4063    return if ($conf & 0x18) != 0x00
4064           || ($mask & 0xa4) != 0xa4;
4065  } elsif ($chip == 2) {
4066    return if $mid != 0x23    # Fintek
4067           || $cid != 0x20;   # F75363SG
4068    return if ($conf & 0x1a) != 0x00
4069           || ($mask & 0x84) != 0x00; 
4070  }
4071
4072  # For compatibility with the LM86, some registers are mirrored
4073  # to alternative locations
4074  return if $conf != i2c_smbus_read_byte_data($file, 0x09);
4075  foreach my $i (0x04, 0x05, 0x07, 0x08) {
4076    return if i2c_smbus_read_byte_data($file, $i)
4077           != i2c_smbus_read_byte_data($file, $i+6);
4078  }
4079
4080  return 8;
4081}
4082
4083# $_[0]: Chip to detect
4084#   (0 = ADM1029)
4085# $_[1]: A reference to the file descriptor to access this chip.
4086# $_[2]: Address (unused)
4087# Returns: undef if not detected, 6 if detected.
4088# Registers used:
4089#   0x02, 0x03: Fan support
4090#   0x06: Temperature support
4091#   0x07, 0x08, 0x09: Fan config
4092#   0x0d: Manufacturer ID
4093#   0x0e: Chip ID / die revision
4094sub adm1029_detect
4095{
4096  my ($chip, $file, $addr) = @_;
4097  my $mid = i2c_smbus_read_byte_data($file, 0x0d);
4098  my $cid = i2c_smbus_read_byte_data($file, 0x0e);
4099  my $cfg;
4100
4101  if ($chip == 0) {
4102    return unless $mid == 0x41;             # Analog Devices
4103    return unless ($cid & 0xF0) == 0x00;    # ADM1029
4104
4105    # Extra check on unused bits
4106    $cfg = i2c_smbus_read_byte_data($file, 0x02);
4107    return unless $cfg == 0x03;
4108    $cfg = i2c_smbus_read_byte_data($file, 0x06);
4109    return unless ($cfg & 0xF9) == 0x01;
4110    foreach my $reg (0x03, 0x07, 0x08, 0x09) {
4111      $cfg = i2c_smbus_read_byte_data($file, $reg);
4112      return unless ($cfg & 0xFC) == 0x00;
4113    }
4114
4115    return 7;
4116  }
4117  return;
4118}
4119
4120# $_[0]: Chip to detect
4121#   (0 = ADM1030, 1=ADM1031)
4122# $_[1]: A reference to the file descriptor to access this chip.
4123# $_[2]: Address
4124# Returns: undef if not detected, 3 to 7 (ADM1031) or 9 (ADM1030)
4125#          if detected.
4126# Registers used:
4127#   0x01: Config 2
4128#   0x03: Status 2
4129#   0x0d, 0x0e, 0x0f: Temperature offsets
4130#   0x22: Fan speed config
4131#   0x3d: Chip ID
4132#   0x3e: Manufacturer ID
4133#   0x3f: Die revision
4134sub adm1031_detect
4135{
4136  my ($chip, $file, $addr) = @_;
4137  my $mid = i2c_smbus_read_byte_data($file, 0x3e);
4138  my $cid = i2c_smbus_read_byte_data($file, 0x3d);
4139  my $drev = i2c_smbus_read_byte_data($file, 0x3f);
4140  my $conf2 = i2c_smbus_read_byte_data($file, 0x01);
4141  my $stat2 = i2c_smbus_read_byte_data($file, 0x03);
4142  my $fsc = i2c_smbus_read_byte_data($file, 0x22);
4143  my $lto = i2c_smbus_read_byte_data($file, 0x0d);
4144  my $r1to = i2c_smbus_read_byte_data($file, 0x0e);
4145  my $r2to = i2c_smbus_read_byte_data($file, 0x0f);
4146  my $confidence = 3;
4147
4148  if ($chip == 0) {
4149    return if $mid != 0x41;     # Analog Devices
4150    return if $cid != 0x30;     # ADM1030
4151    $confidence++ if ($drev & 0x70) == 0x00;
4152    $confidence++ if ($conf2 & 0x4A) == 0x00;
4153    $confidence++ if ($stat2 & 0x3F) == 0x00;
4154    $confidence++ if ($fsc & 0xF0) == 0x00;
4155    $confidence++ if ($lto & 0x70) == 0x00;
4156    $confidence++ if ($r1to & 0x70) == 0x00;
4157    return $confidence;
4158  }
4159  if ($chip == 1) {
4160    return if $mid != 0x41;     # Analog Devices
4161    return if $cid != 0x31;     # ADM1031
4162    $confidence++ if ($drev & 0x70) == 0x00;
4163    $confidence++ if ($lto & 0x70) == 0x00;
4164    $confidence++ if ($r1to & 0x70) == 0x00;
4165    $confidence++ if ($r2to & 0x70) == 0x00;
4166    return $confidence;
4167  }
4168  return;
4169}
4170
4171# $_[0]: Chip to detect
4172#   (0 = ADM1033, 1 = ADM1034)
4173# $_[1]: A reference to the file descriptor to access this chip.
4174# $_[2]: Address (unused)
4175# Returns: undef if not detected, 4 or 6 if detected.
4176# Registers used:
4177#   0x3d: Chip ID
4178#   0x3e: Manufacturer ID
4179#   0x3f: Die revision
4180sub adm1034_detect
4181{
4182  my ($chip, $file, $addr) = @_;
4183  my $mid = i2c_smbus_read_byte_data($file, 0x3e);
4184  my $cid = i2c_smbus_read_byte_data($file, 0x3d);
4185  my $drev = i2c_smbus_read_byte_data($file, 0x3f);
4186
4187  if ($chip == 0) {
4188    return if $mid != 0x41;     # Analog Devices
4189    return if $cid != 0x33;     # ADM1033
4190    return if ($drev & 0xf8) != 0x00;
4191    return 6 if $drev == 0x02;
4192    return 4;
4193  }
4194  if ($chip == 1) {
4195    return if $mid != 0x41;     # Analog Devices
4196    return if $cid != 0x34;     # ADM1034
4197    return if ($drev & 0xf8) != 0x00;
4198    return 6 if $drev == 0x02;
4199    return 4;
4200  }
4201  return
4202}
4203
4204# $_[0]: Chip to detect
4205#   (0 = ADT7467/ADT7468, 1 = ADT7476, 2 = ADT7462, 3 = ADT7466,
4206#    4 = ADT7470)
4207# $_[1]: A reference to the file descriptor to access this chip.
4208# $_[2]: Address
4209# Returns: undef if not detected, 5 or 7 if detected.
4210# Registers used:
4211#   0x3d: Chip ID
4212#   0x3e: Manufacturer ID
4213#   0x3f: Die revision
4214sub adt7467_detect
4215{
4216  my ($chip, $file, $addr) = @_;
4217  my $mid = i2c_smbus_read_byte_data($file, 0x3e);
4218  my $cid = i2c_smbus_read_byte_data($file, 0x3d);
4219  my $drev = i2c_smbus_read_byte_data($file, 0x3f);
4220
4221  if ($chip == 0) {
4222    return if $mid != 0x41;     # Analog Devices
4223    return if $cid != 0x68;     # ADT7467
4224    return if ($drev & 0xf0) != 0x70;
4225    return 7 if ($drev == 0x71 || $drev == 0x72);
4226    return 5;
4227  }
4228  if ($chip == 1) {
4229    return if $mid != 0x41;     # Analog Devices
4230    return if $cid != 0x76;     # ADT7476
4231    return if ($drev & 0xf0) != 0x60;
4232    return 7 if ($drev == 0x69);
4233    return 5;
4234  }
4235  if ($chip == 2) {
4236    return if $mid != 0x41;     # Analog Devices
4237    return if $cid != 0x62;     # ADT7462
4238    return if ($drev & 0xf0) != 0x00;
4239    return 7 if ($drev == 0x04);
4240    return 5;
4241  }
4242  if ($chip == 3) {
4243    return if $mid != 0x41;     # Analog Devices
4244    return if $cid != 0x66;     # ADT7466
4245    return if ($drev & 0xf0) != 0x00;
4246    return 7 if ($drev == 0x02);
4247    return 5;
4248  }
4249  if ($chip == 4) {
4250    return if $mid != 0x41;     # Analog Devices
4251    return if $cid != 0x70;     # ADT7470
4252    return if ($drev & 0xf0) != 0x00;
4253    return 7 if ($drev == 0x00);
4254    return 5;
4255  }
4256  return
4257}
4258
4259# $_[0]: Chip to detect
4260#   (0 = ADT7473, 1 = ADT7475)
4261# $_[1]: A reference to the file descriptor to access this chip.
4262# $_[2]: Address (unused)
4263# Returns: undef if not detected, 5 if detected.
4264# Registers used:
4265#   0x3d: Chip ID
4266#   0x3e: Manufacturer ID
4267sub adt7473_detect
4268{
4269  my ($chip, $file, $addr) = @_;
4270  my $mid = i2c_smbus_read_byte_data($file, 0x3e);
4271  my $cid = i2c_smbus_read_byte_data($file, 0x3d);
4272
4273  if ($chip == 0) {
4274    return if $mid != 0x41;     # Analog Devices
4275    return if $cid != 0x73;     # ADT7473
4276    return 5;
4277  }
4278  if ($chip == 1) {
4279    return if $mid != 0x41;     # Analog Devices
4280    return if $cid != 0x75;     # ADT7475
4281    return 5;
4282  }
4283  return
4284}
4285
4286# $_[0]: Chip to detect
4287#   (0 = aSC7512, 1 = aSC7611, 2 = aSC7621)
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#   0x3e: Manufacturer ID (0x61)
4293#   0x3f: Version
4294
4295sub andigilog_detect
4296{
4297  my ($chip, $file, $addr) = @_;
4298  my $mid = i2c_smbus_read_byte_data($file, 0x3e);
4299  my $cid = i2c_smbus_read_byte_data($file, 0x3f);
4300
4301  return if ($mid != 0x61);
4302
4303  if ($chip == 0) {
4304    return if $cid != 0x62;
4305    return 5;
4306  }
4307
4308  if ($chip == 1) {
4309    return if $cid != 0x69;
4310    return 5;
4311  }
4312
4313  if ($chip == 2) {
4314    return if $cid != 0x6C;
4315    return 5;
4316  }
4317
4318  return;
4319}
4320
4321# $_[0]: Chip to detect
4322#   (0 = aSC7511)
4323# $_[1]: A reference to the file descriptor to access this chip.
4324# $_[2]: Address (unused)
4325# Returns: undef if not detected, 1 if detected.
4326# Registers used:
4327#   0xfe: Manufacturer ID
4328#   0xff: Die Code
4329sub andigilog_aSC7511_detect
4330{
4331  my ($chip, $file, $addr) = @_;
4332  my $mid = i2c_smbus_read_byte_data($file, 0xfe);
4333  my $die = i2c_smbus_read_byte_data($file, 0xff);
4334
4335  if ($chip == 0) {
4336    return if $mid != 0x61;     # Andigilog
4337    if ($die == 0x0) {
4338        return 3;
4339    } else {
4340        return 1;
4341    }
4342  }
4343  return;
4344}
4345
4346# $_[0]: Vendor to check for
4347#   (0x01 = National Semi, 0x41 = Analog Dev, 0x5c = SMSC)
4348# $_[1]: A reference to the file descriptor to access this chip.
4349# #_[2]: Base address.
4350# Returns: undef if not detected, (7) or (8) if detected.
4351# Registers used: 0x3e == Vendor register.
4352#                 0x3d == Device ID register (Analog Devices only).
4353#                 0x3f == Version/Stepping register.
4354# Constants used: 0x01 == National Semiconductor Vendor Id.
4355#                 0x41 == Analog Devices Vendor Id.
4356#                 0x5c == SMSC Vendor Id.
4357#                 0x60 == Version number. The lower 4 stepping
4358#                         bits are masked and ignored.
4359sub lm85_detect
4360{
4361  my ($vendor,$file,$addr) = @_;
4362  return if (i2c_smbus_read_byte_data($file,0x3e)) != $vendor ;
4363
4364  my $verstep = i2c_smbus_read_byte_data($file,0x3f);
4365  return if ($verstep & 0xf0) != 0x60;
4366
4367  if ($vendor == 0x41) # Analog Devices
4368  {
4369    return if i2c_smbus_read_byte_data($file, 0x3d) != 0x27;
4370    return (8);
4371  }
4372
4373  if ($vendor == 0x5c) # SMSC
4374  {
4375    # Return undef if this is a SCH5027
4376    return if $verstep >= 0x69 and
4377        i2c_smbus_read_byte_data($file, 0xba) == 0x0f;
4378  }
4379
4380  return (7);
4381}
4382
4383# $_[0]: A reference to the file descriptor to access this chip.
4384# $_[1]: Address
4385# Returns: undef if not detected, (7) if detected.
4386# Registers used: 0x3E, 0x3F
4387#        Assume lower 2 bits of reg 0x3F are for revisions.
4388sub lm87_detect
4389{
4390  my ($file,$addr) = @_;
4391  return if (i2c_smbus_read_byte_data($file,0x3e)) != 0x02;
4392  return if (i2c_smbus_read_byte_data($file,0x3f) & 0xfc) != 0x04;
4393  return (7);
4394}
4395 
4396# $_[0]: Chip to detect (0 = W83781D, 1 = W83782D, 2 = W83783S,
4397#                        3 = W83627HF, 4 = AS99127F (rev.1),
4398#                        5 = AS99127F (rev.2), 6 = ASB100, 7 = W83791D,
4399#                        8 = W83792D, 9 = W83627EHF 10 = W83627DHG)
4400# $_[1]: A reference to the file descriptor to access this chip.
4401# $_[2]: Address
4402# Returns: undef if not detected, (8,addr1,addr2) if detected, but only
4403#          if the LM75 chip emulation is enabled.
4404# Registers used:
4405#   0x48: Full I2C Address
4406#   0x4a: I2C addresses of emulated LM75 chips
4407#   0x4e: Vendor ID byte selection, and bank selection
4408#   0x4f: Vendor ID
4409#   0x58: Device ID (only when in bank 0)
4410# Note: Fails if the W8378xD is not in bank 0!
4411# Note: Detection overrules a previous LM78 detection
4412# Note: Asus chips do not have their I2C address at register 0x48?
4413#       AS99127F rev.1 and ASB100 have 0x00, confirmation wanted for
4414#       AS99127F rev.2.
4415sub w83781d_detect
4416{
4417  my ($reg1,$reg2,@res);
4418  my ($chip,$file,$addr) = @_;
4419
4420  return unless (i2c_smbus_read_byte_data($file,0x48) == $addr)
4421    or ($chip >= 4 && $chip <= 6);
4422
4423  $reg1 = i2c_smbus_read_byte_data($file,0x4e);
4424  $reg2 = i2c_smbus_read_byte_data($file,0x4f);
4425  if ($chip == 4) { # Asus AS99127F (rev.1)
4426    return unless (($reg1 & 0x80) == 0x00 and $reg2 == 0xc3) or 
4427                  (($reg1 & 0x80) == 0x80 and $reg2 == 0x12);
4428  } elsif ($chip == 6) { # Asus ASB100
4429    return unless (($reg1 & 0x80) == 0x00 and $reg2 == 0x94) or 
4430                  (($reg1 & 0x80) == 0x80 and $reg2 == 0x06);
4431  } else { # Winbond and Asus AS99127F (rev.2)
4432    return unless (($reg1 & 0x80) == 0x00 and $reg2 == 0xa3) or 
4433                  (($reg1 & 0x80) == 0x80 and $reg2 == 0x5c);
4434  }
4435
4436  return unless ($reg1 & 0x07) == 0x00;
4437
4438  $reg1 = i2c_smbus_read_byte_data($file,0x58);
4439  return if $chip == 0 and ($reg1 != 0x10 && $reg1 != 0x11);
4440  return if $chip == 1 and  $reg1 != 0x30;
4441  return if $chip == 2 and  $reg1 != 0x40;
4442  return if $chip == 3 and  $reg1 != 0x21;
4443  return if $chip == 4 and  $reg1 != 0x31;
4444  return if $chip == 5 and  $reg1 != 0x31;
4445  return if $chip == 6 and  $reg1 != 0x31;
4446  return if $chip == 7 and  $reg1 != 0x71;
4447  return if $chip == 8 and  $reg1 != 0x7a;
4448  return if $chip == 9 and  $reg1 != 0xa1;
4449  return if $chip == 10 and  $reg1 != 0xa2;
4450  $reg1 = i2c_smbus_read_byte_data($file,0x4a);
4451  # Default address is 0x2d
4452  @res = ($addr != 0x2d) ? (7) : (8);
4453  return @res if $chip == 9; # No subclients
4454  push @res, ($reg1 & 0x07) + 0x48 unless $reg1 & 0x08;
4455  push @res, (($reg1 & 0x70) >> 4) + 0x48 unless ($reg1 & 0x80 or $chip == 2);
4456  return @res;
4457}
4458 
4459# $_[0]: Chip to detect (0 = W83793)
4460# $_[1]: A reference to the file descriptor to access this chip.
4461# $_[2]: Address
4462# Returns: undef if not detected
4463#          6 if detected and bank different from 0
4464#          (8,addr1,addr2) if detected, band is 0 and LM75 chip emulation
4465#          is enabled
4466# Registers used:
4467#   0x0b: Full I2C Address
4468#   0x0c: I2C addresses of emulated LM75 chips
4469#   0x00: Vendor ID byte selection, and bank selection(Bank 0,1,2)
4470#   0x0d: Vendor ID(Bank 0,1,2)
4471#   0x0e: Device ID(Bank 0,1,2)
4472sub w83793_detect
4473{
4474  my ($bank, $reg, @res);
4475  my ($chip, $file, $addr) = @_;
4476
4477  $bank = i2c_smbus_read_byte_data($file, 0x00);
4478  $reg = i2c_smbus_read_byte_data($file, 0x0d);
4479
4480  return unless (($bank & 0x80) == 0x00 and $reg == 0xa3) or 
4481                (($bank & 0x80) == 0x80 and $reg == 0x5c);
4482
4483  $reg = i2c_smbus_read_byte_data($file, 0x0e);
4484  return if $chip == 0 and $reg != 0x7b;
4485
4486# If bank 0 is selected, we can do more checks
4487  return 6 unless ($bank & 0x07) == 0;
4488  $reg = i2c_smbus_read_byte_data($file, 0x0b);
4489  return unless ($reg == ($addr << 1));
4490
4491  $reg = i2c_smbus_read_byte_data($file, 0x0c);
4492  @res = (8);
4493  push @res, ($reg & 0x07) + 0x48 unless $reg & 0x08;
4494  push @res, (($reg & 0x70) >> 4) + 0x48 unless $reg & 0x80;
4495  return @res;
4496}
4497
4498# $_[0]: A reference to the file descriptor to access this chip.
4499# $_[1]: Address
4500# Returns: undef if not detected, 3 if detected
4501# Registers used:
4502#   0x48: Full I2C Address
4503#   0x4e: Vendor ID byte selection
4504#   0x4f: Vendor ID
4505#   0x58: Device ID
4506# Note that the datasheet was useless and this detection routine
4507# is based on dumps we received from users. Also, the W83781SD is *NOT*
4508# a hardware monitoring chip as far as we know, but we still want to
4509# detect it so that people won't keep reporting it as an unknown chip
4510# we should investigate about.
4511sub w83791sd_detect
4512{
4513  my ($file, $addr) = @_;
4514  my ($reg1, $reg2);
4515
4516  return unless (i2c_smbus_read_byte_data($file, 0x48) == $addr);
4517
4518  $reg1 = i2c_smbus_read_byte_data($file, 0x4e);
4519  $reg2 = i2c_smbus_read_byte_data($file, 0x4f);
4520  return unless (!($reg1 & 0x80) && $reg2 == 0xa3)
4521             || (($reg1 & 0x80) && $reg2 == 0x5c);
4522
4523  $reg1 = i2c_smbus_read_byte_data($file, 0x58);
4524  return unless $reg1 == 0x72;
4525
4526  return 3;
4527}
4528
4529# $_[0]: Chip to detect (0 = ASM58, 1 = AS2K129R, 2 = ???)
4530# $_[1]: A reference to the file descriptor to access this chip
4531# $_[2]: Address (unused)
4532# Returns: undef if not detected, 5 if detected
4533# Registers used:
4534#   0x4e: Vendor ID high byte
4535#   0x4f: Vendor ID low byte
4536#   0x58: Device ID
4537# Note: The values were given by Alex van Kaam, we don't have datasheets
4538#       to confirm.
4539sub mozart_detect
4540{
4541  my ($vid,$dev);
4542  my ($chip,$file,$addr) = @_;
4543
4544  $vid = (i2c_smbus_read_byte_data($file,0x4e) << 8)
4545       +  i2c_smbus_read_byte_data($file,0x4f);
4546  $dev = i2c_smbus_read_byte_data($file,0x58);
4547
4548  return if ($chip == 0) and ($dev != 0x56 || $vid != 0x9436);
4549  return if ($chip == 1) and ($dev != 0x56 || $vid != 0x9406);
4550  return if ($chip == 2) and ($dev != 0x10 || $vid != 0x5ca3);
4551
4552  return 5;
4553}
4554
4555# $_[0]: Chip to detect (0 = W83781D, 1 = W83782D, 3 = W83627HF,
4556#                        9 = W83627EHF 10 = W83627DHG)
4557# $_[1]: ISA address
4558# $_[2]: I2C file handle
4559# $_[3]: I2C address
4560sub w83781d_alias_detect
4561{
4562  my ($chip,$isa_addr,$file,$i2c_addr) = @_;
4563  my $i;
4564  my $readproc = sub { isa_read_byte $isa_addr + 5, $isa_addr + 6, @_ };
4565  return 0 unless &$readproc(0x48) == $i2c_addr;
4566  for ($i = 0x2b; $i <= 0x3d; $i ++) {
4567    return 0 unless &$readproc($i) == i2c_smbus_read_byte_data($file,$i);
4568  }
4569  return 1;
4570}
4571
4572# $_[0]: Chip to detect (0 = W83781D, 1 = W83782D)
4573# $_[1]: Address
4574# Returns: undef if not detected, (8) if detected.
4575sub w83781d_isa_detect
4576{
4577  my ($chip,$addr) = @_ ;
4578  my ($reg1,$reg2);
4579  my $val = inb ($addr + 1);
4580  return if inb ($addr + 2) != $val or inb ($addr + 3) != $val or
4581            inb ($addr + 7) != $val;
4582
4583  $val = inb($addr + 5);
4584  outb($addr+5, ~$val & 0x7f);
4585  if ((inb ($addr+5) & 0x7f) != (~ $val & 0x7f)) {
4586    outb($addr+5,$val);
4587    return;
4588  }
4589
4590  my $read_proc = sub { isa_read_byte $addr + 5, $addr + 6, @_ };
4591  $reg1 = &$read_proc(0x4e);
4592  $reg2 = &$read_proc(0x4f);
4593  return unless (($reg1 & 0x80) == 0x00 and $reg2 == 0xa3) or 
4594                (($reg1 & 0x80) == 0x80 and $reg2 == 0x5c);
4595  return unless ($reg1 & 0x07) == 0x00;
4596  $reg1 = &$read_proc(0x58);
4597  return if $chip == 0 and  ($reg1 & 0xfe) != 0x10;
4598  return if $chip == 1 and  ($reg1 & 0xfe) != 0x30;
4599
4600  return 8;
4601}
4602
4603# $_[0]: Chip to detect (0 = Revision 0x00, 1 = Revision 0x80)
4604# $_[1]: A reference to the file descriptor to access this chip.
4605# $_[2]: Address
4606# Returns: undef if not detected, (6) if detected.
4607# Registers used:
4608#   0x00: Device ID
4609#   0x01: Revision ID
4610#   0x03: Configuration
4611# Mediocre detection
4612sub gl518sm_detect
4613{
4614  my $reg;
4615  my ($chip,$file,$addr) = @_;
4616  return unless i2c_smbus_read_byte_data($file,0x00) == 0x80;
4617  return unless (i2c_smbus_read_byte_data($file,0x03) & 0x80) == 0x00;
4618  $reg = i2c_smbus_read_byte_data($file,0x01);
4619  return unless ($chip == 0 and $reg == 0x00) or
4620                ($chip == 1 and $reg == 0x80);
4621  return (6);
4622}
4623
4624# $_[0]: A reference to the file descriptor to access this chip.
4625# $_[1]: Address
4626# Returns: undef if not detected, (5) if detected.
4627# Registers used:
4628#   0x00: Device ID
4629#   0x01: Revision ID
4630#   0x03: Configuration
4631# Mediocre detection
4632sub gl520sm_detect
4633{
4634  my ($file,$addr) = @_;
4635  return unless i2c_smbus_read_byte_data($file,0x00) == 0x20;
4636  return unless (i2c_smbus_read_byte_data($file,0x03) & 0x80) == 0x00;
4637  # The line below must be better checked before I dare to use it.
4638  # return unless i2c_smbus_read_byte_data($file,0x01) == 0x00;
4639  return (5);
4640}
4641
4642# $_[0]: A reference to the file descriptor to access this chip.
4643# $_[1]: Address
4644# Returns: undef if not detected, (5) if detected.
4645# Registers used:
4646#   0x00: Device ID
4647# Mediocre detection
4648sub gl525sm_detect
4649{
4650  my ($file,$addr) = @_;
4651  return unless i2c_smbus_read_byte_data($file,0x00) == 0x25;
4652  return (5);
4653}
4654
4655# $_[0]: Chip to detect (0 = ADM9240, 1 = DS1780, 2 = LM81)
4656# $_[1]: A reference to the file descriptor to access this chip.
4657# $_[2]: Address
4658# Returns: undef if not detected, (7) if detected.
4659# Registers used:
4660#   0x3e: Company ID
4661#   0x40: Configuration
4662#   0x48: Full I2C Address
4663# Note: Detection overrules a previous LM78 detection
4664sub adm9240_detect
4665{
4666  my $reg;
4667  my ($chip, $file,$addr) = @_;
4668  $reg = i2c_smbus_read_byte_data($file,0x3e);
4669  return unless ($chip == 0 and $reg == 0x23) or
4670                ($chip == 1 and $reg == 0xda) or
4671                ($chip == 2 and $reg == 0x01);
4672  return unless (i2c_smbus_read_byte_data($file,0x40) & 0x80) == 0x00;
4673  return unless i2c_smbus_read_byte_data($file,0x48) == $addr;
4674 
4675  return (7);
4676}
4677
4678# $_[0]: Chip to detect (0 = ADM1022, 1 = THMC50, 2 = ADM1028)
4679# $_[1]: A reference to the file descriptor to access this chip.
4680# $_[2]: Address
4681# Returns: undef if not detected, (8) if detected.
4682# Registers used:
4683#   0x3e: Company ID
4684#   0x3f: Revision
4685#   0x40: Configuration
4686# Note: Detection overrules a previous LM78 or ADM9240 detection
4687sub adm1022_detect
4688{
4689  my $reg;
4690  my ($chip, $file,$addr) = @_;
4691  $reg = i2c_smbus_read_byte_data($file,0x3e);
4692  return unless ($chip == 0 and $reg == 0x41) or
4693                ($chip == 1 and $reg == 0x49) or
4694                ($chip == 2 and $reg == 0x41);
4695  $reg = i2c_smbus_read_byte_data($file,0x40);
4696  return if ($reg & 0x10);                      # Soft Reset always reads 0
4697  return if ($chip != 0 and ($reg & 0x80));     # Reserved on THMC50 and ADM1028
4698  $reg = i2c_smbus_read_byte_data($file, 0x3f) & 0xf0;
4699  return unless ($chip == 0 and $reg == 0xc0) or
4700                ($chip == 1 and $reg == 0xc0) or
4701                ($chip == 2 and $reg == 0xd0);
4702  return (8);
4703}
4704
4705# $_[0]: Chip to detect (0 = ADM1025, 1 = NE1619)
4706# $_[1]: A reference to the file descriptor to access this chip.
4707# $_[2]: Address
4708# Returns: undef if not detected, (8) if detected.
4709# Registers used:
4710#   0x3e: Company ID
4711#   0x3f: Revision
4712#   0x40: Configuration
4713#   0x41: Status 1
4714#   0x42: Status 2
4715# Note: Detection overrules a previous LM78 or ADM9240 detection
4716sub adm1025_detect
4717{
4718  my $reg;
4719  my ($chip, $file,$addr) = @_;
4720
4721  $reg = i2c_smbus_read_byte_data($file,0x3e);
4722  return if ($chip == 0) and ($reg != 0x41);
4723  return if ($chip == 1) and ($reg != 0xA1);
4724
4725  return unless (i2c_smbus_read_byte_data($file,0x40) & 0x80) == 0x00;
4726  return unless (i2c_smbus_read_byte_data($file,0x41) & 0xC0) == 0x00;
4727  return unless (i2c_smbus_read_byte_data($file,0x42) & 0xBC) == 0x00;
4728  return unless (i2c_smbus_read_byte_data($file,0x3f) & 0xf0) == 0x20;
4729
4730  return (8);
4731}
4732
4733# $_[0]: Chip to detect (0 = ADM1026)
4734# $_[1]: A reference to the file descriptor to access this chip.
4735# $_[2]: Address
4736# Returns: undef if not detected, (8) if detected.
4737# Registers used:
4738#   0x16: Company ID
4739#   0x17: Revision
4740sub adm1026_detect
4741{
4742  my $reg;
4743  my ($chip, $file,$addr) = @_;
4744  $reg = i2c_smbus_read_byte_data($file,0x16);
4745  return unless ($reg == 0x41);
4746  return unless (i2c_smbus_read_byte_data($file,0x17) & 0xf0) == 0x40;
4747  return (8);
4748}
4749
4750# $_[0]: Chip to detect (0 = ADM1024)
4751# $_[1]: A reference to the file descriptor to access this chip.
4752# $_[2]: Address
4753# Returns: undef if not detected, (8) if detected.
4754# Registers used:
4755#   0x3e: Company ID
4756#   0x3f: Revision
4757#   0x40: Configuration
4758sub adm1024_detect
4759{
4760  my $reg;
4761  my ($chip, $file,$addr) = @_;
4762  $reg = i2c_smbus_read_byte_data($file,0x3e);
4763  return unless ($reg == 0x41);
4764  return unless (i2c_smbus_read_byte_data($file,0x40) & 0x80) == 0x00;
4765  return unless (i2c_smbus_read_byte_data($file,0x3f) & 0xf0) == 0x10;
4766  return (8);
4767}
4768
4769# $_[0]: Chip to detect
4770#   (0 = ADM1021, 1 = ADM1021A/ADM1023, 2 = MAX1617, 3 = MAX1617A, 4 = THMC10,
4771#    5 = LM84, 6 = GL523, 7 = MC1066)
4772# $_[1]: A reference to the file descriptor to access this chip.
4773# $_[2]: Address
4774# Returns: undef if not detected, 3 if simply detected, 5 if detected and
4775#          manufacturer ID matches, 7 if detected and manufacturer ID and
4776#          revision match
4777# Registers used:
4778#   0x04: Company ID (LM84 only)
4779#   0xfe: Company ID (all but LM84 and MAX1617)
4780#   0xff: Revision (ADM1021, ADM1021A/ADM1023 and MAX1617A)
4781#   0x02: Status
4782#   0x03: Configuration
4783#   0x04: Conversion rate
4784#   0x00-0x01, 0x05-0x08: Temperatures (MAX1617 and LM84)
4785# Note: Especially the MAX1617 has very bad detection; we give it a low
4786# confidence value.
4787sub adm1021_detect
4788{
4789  my ($chip, $file, $addr) = @_;
4790  my $man_id = i2c_smbus_read_byte_data($file, 0xfe);
4791  my $rev = i2c_smbus_read_byte_data($file, 0xff);
4792  my $conf = i2c_smbus_read_byte_data($file, 0x03);
4793  my $status = i2c_smbus_read_byte_data($file, 0x02);
4794  my $convrate = i2c_smbus_read_byte_data($file, 0x04);
4795
4796  # Check manufacturer IDs and product revisions when available
4797  return if $chip == 0 and $man_id != 0x41 ||
4798                          ($rev & 0xf0) != 0x00;
4799  return if $chip == 1 and $man_id != 0x41 ||
4800                          ($rev & 0xf0) != 0x30;
4801  return if $chip == 3 and $man_id != 0x4d ||
4802                           $rev != 0x01;
4803  return if $chip == 4 and $man_id != 0x49;
4804  return if $chip == 5 and $convrate != 0x00;
4805  return if $chip == 6 and $man_id != 0x23;
4806  return if $chip == 7 and $man_id != 0x54;
4807
4808  # Check unused bits
4809  if ($chip == 5) # LM84
4810  {
4811    return if ($status & 0xab) != 0;
4812    return if ($conf & 0x7f) != 0;
4813  }
4814  else
4815  {
4816    return if ($status & 0x03) != 0;
4817    return if ($conf & 0x3f) != 0;
4818    return if ($convrate & 0xf8) != 0;
4819  }
4820
4821  # Extra checks for MAX1617 and LM84, since those are often misdetected
4822  # We verify several assertions (6 for the MAX1617, 4 for the LM84) and
4823  # discard the chip if any fail. Note that these checks are not done
4824  # by the adm1021 driver.
4825  if ($chip == 2 || $chip == 5)
4826  {
4827    my $lte = i2c_smbus_read_byte_data($file, 0x00);
4828    my $rte = i2c_smbus_read_byte_data($file, 0x01);
4829    my $lhi = i2c_smbus_read_byte_data($file, 0x05);
4830    my $rhi = i2c_smbus_read_byte_data($file, 0x07);
4831    my $llo = i2c_smbus_read_byte_data($file, 0x06);
4832    my $rlo = i2c_smbus_read_byte_data($file, 0x08);
4833
4834    # If all registers hold the same value, it has to be a misdetection
4835    return if $lte == $rte and $lte == $lhi and $lte == $rhi
4836           and $lte == $llo and $lte == $rlo;
4837
4838    # Negative temperatures
4839    return if ($lte & 0x80) or ($rte & 0x80);
4840    # Negative high limits
4841    return if ($lhi & 0x80) or ($rhi & 0x80);
4842    # Low limits over high limits
4843    if ($chip != 5) # LM84 doesn't have low limits
4844    {
4845      $llo-=256 if ($llo & 0x80);
4846      $rlo-=256 if ($rlo & 0x80);
4847      return if ($llo > $lhi) or ($rlo > $rhi);
4848    }
4849  }
4850
4851  return 3 if ($chip == 2) or ($chip == 5);
4852  return 7 if $chip <= 3;
4853  return 5;
4854}
4855
4856# $_[0]: Chip to detect
4857#   (0 = MAX1668, 1 = MAX1805, 2 = MAX1989)
4858# $_[1]: A reference to the file descriptor to access this chip.
4859#        We may assume an i2c_set_slave_addr was already done.
4860# $_[2]: Address
4861# Returns: undef if not detected, 7 if detected
4862# Registers used:
4863#   0xfe: Company ID
4864#   0xff: Device ID
4865sub max1668_detect
4866{
4867  my ($chip, $file, $addr) = @_;
4868  my $man_id = i2c_smbus_read_byte_data($file, 0xfe);
4869  my $dev_id = i2c_smbus_read_byte_data($file, 0xff);
4870
4871  return if $man_id != 0x4d;
4872  return if $chip == 0 and $dev_id != 0x03;
4873  return if $chip == 1 and $dev_id != 0x05;
4874  return if $chip == 2 and $dev_id != 0x0b;
4875
4876  return 7;
4877}
4878
4879# $_[0]: Chip to detect
4880#   (0 = MAX1619)
4881# $_[1]: A reference to the file descriptor to access this chip.
4882# $_[2]: Address
4883# Returns: undef if not detected, 7 if detected
4884# Registers used:
4885#   0xfe: Company ID
4886#   0xff: Device ID
4887#   0x02: Status
4888#   0x03: Configuration
4889#   0x04: Conversion rate
4890sub max1619_detect
4891{
4892  my ($chip, $file, $addr) = @_;
4893  my $man_id = i2c_smbus_read_byte_data($file, 0xfe);
4894  my $dev_id = i2c_smbus_read_byte_data($file, 0xff);
4895  my $conf = i2c_smbus_read_byte_data($file, 0x03);
4896  my $status = i2c_smbus_read_byte_data($file, 0x02);
4897  my $convrate = i2c_smbus_read_byte_data($file, 0x04);
4898
4899  return if $man_id != 0x4D
4900    or $dev_id != 0x04
4901    or ($conf & 0x03)
4902    or ($status & 0x61)
4903    or $convrate >= 8;
4904
4905  return 7;
4906}
4907
4908# $_[0]: A reference to the file descriptor to access this chip.
4909# $_[1]: Address (unused)
4910# Returns: undef if not detected, 6 if detected.
4911# Registers used:
4912#   0x28: User ID
4913#   0x29: User ID2
4914#   0x2A: Version ID
4915
4916sub ite_overclock_detect
4917{
4918  my ($file, $addr) = @_;
4919
4920  my $uid1 = i2c_smbus_read_byte_data($file, 0x28);
4921  my $uid2 = i2c_smbus_read_byte_data($file, 0x29);
4922  return if $uid1 != 0x83
4923         || $uid2 != 0x12;
4924
4925  return 6;
4926}
4927
4928# $_[0]: Chip to detect (0 = IT8712F)
4929# $_[1]: A reference to the file descriptor to access this chip.
4930# $_[2]: Address
4931# Returns: undef if not detected, 7 or 8 if detected (tops LM78).
4932# Registers used:
4933#   0x00: Configuration
4934#   0x48: Full I2C Address
4935#   0x58: Mfr ID
4936#   0x5b: Device ID (not on IT8705)
4937sub ite_detect
4938{
4939  my $reg;
4940  my ($chip,$file,$addr) = @_;
4941  return unless i2c_smbus_read_byte_data($file,0x48) == $addr;
4942  return unless (i2c_smbus_read_byte_data($file, 0x00) & 0x90) == 0x10;
4943  return unless i2c_smbus_read_byte_data($file,0x58) == 0x90;
4944  return if $chip == 0 and i2c_smbus_read_byte_data($file,0x5b) != 0x12;
4945  return (7 + ($addr == 0x2d));
4946}
4947
4948
4949# $_[0]: Chip to detect (0 = IT8712F)
4950# $_[1]: ISA address
4951# $_[2]: I2C file handle
4952# $_[3]: I2C address
4953sub ite_alias_detect
4954{
4955  my ($chip,$isa_addr,$file,$i2c_addr) = @_;
4956  my $i;
4957  my $readproc = sub { isa_read_byte $isa_addr + 5, $isa_addr + 6, @_ };
4958  return 0 unless &$readproc(0x48) == $i2c_addr;
4959  for ($i = 0x30; $i <= 0x45; $i++) {
4960    return 0 unless &$readproc($i) == i2c_smbus_read_byte_data($file,$i);
4961  }
4962  return 1;
4963}
4964
4965# $_[0]: A reference to the file descriptor to access this chip
4966# $_[1]: Address
4967# Returns: 8 for a memory eeprom
4968# Registers used:
4969#   0-63: SPD Data and Checksum
4970sub eeprom_detect
4971{
4972  my ($file, $addr) = @_;
4973  my $checksum = 0;
4974
4975  # Check the checksum for validity (works for most DIMMs and RIMMs)
4976  for (my $i = 0; $i <= 62; $i++) {
4977    $checksum += i2c_smbus_read_byte_data($file, $i);
4978  }
4979  $checksum &= 255;
4980
4981  return 8
4982    if $checksum == i2c_smbus_read_byte_data($file, 63);
4983
4984  return;
4985}
4986
4987# $_[0]: A reference to the file descriptor to access this chip.
4988# $_[1]: Address
4989# Returns: undef if not detected, 8 if detected.
4990# Registers used:
4991#   0x00..0x07: DDC signature
4992sub ddcmonitor_detect
4993{
4994  my ($file,$addr) = @_;
4995
4996  return unless
4997    i2c_smbus_read_byte_data($file,0x00) == 0x00 and
4998    i2c_smbus_read_byte_data($file,0x01) == 0xFF and
4999    i2c_smbus_read_byte_data($file,0x02) == 0xFF and
5000    i2c_smbus_read_byte_data($file,0x03) == 0xFF and
5001    i2c_smbus_read_byte_data($file,0x04) == 0xFF and
5002    i2c_smbus_read_byte_data($file,0x05) == 0xFF and
5003    i2c_smbus_read_byte_data($file,0x06) == 0xFF and
5004    i2c_smbus_read_byte_data($file,0x07) == 0x00;
5005
5006  return 8;
5007}
5008
5009# $_[0]: A reference to the file descriptor to access this chip.
5010# $_[1]: Address
5011# Returns: undef if not detected, (8) if detected.
5012# Registers used:
5013#   0x00-0x02: Identification ('P','E','G' -> Pegasus ? :-) aka Poseidon I
5014sub fscpeg_detect
5015{
5016  my ($file,$addr) = @_;
5017  # check the first 3 registers
5018  if (i2c_smbus_read_byte_data($file,0x00) != 0x50) {
5019        return;
5020  }
5021  if (i2c_smbus_read_byte_data($file,0x01) != 0x45) {
5022        return;
5023  }
5024  if (i2c_smbus_read_byte_data($file,0x02) != 0x47) {
5025        return;
5026  }
5027  return (8);
5028}
5029
5030# $_[0]: A reference to the file descriptor to access this chip.
5031# $_[1]: Address
5032# Returns: undef if not detected, (8) if detected.
5033# Registers used:
5034#   0x00-0x02: Identification 'P','O','S' -> Poseideon II
5035sub fscpos_detect
5036{
5037  my ($file,$addr) = @_;
5038  # check the first 3 registers
5039  if (i2c_smbus_read_byte_data($file,0x00) != 0x50) {
5040        return;
5041  }
5042  if (i2c_smbus_read_byte_data($file,0x01) != 0x4F) {
5043        return;
5044  }
5045  if (i2c_smbus_read_byte_data($file,0x02) != 0x53) {
5046        return;
5047  }
5048  return (8);
5049}
5050
5051# $_[0]: A reference to the file descriptor to access this chip.
5052# $_[1]: Address
5053# Returns: undef if not detected, (8) if detected.
5054# Registers used:
5055#   0x00-0x02: Identification ('S','C','Y')
5056sub fscscy_detect
5057{
5058  my ($file,$addr) = @_;
5059  # check the first 3 registers
5060  if (i2c_smbus_read_byte_data($file,0x00) != 0x53) {
5061        return;
5062  }
5063  if (i2c_smbus_read_byte_data($file,0x01) != 0x43) {
5064        return;
5065  }
5066  if (i2c_smbus_read_byte_data($file,0x02) != 0x59) {
5067        return;
5068  }
5069  return (8);
5070}
5071
5072# $_[0]: A reference to the file descriptor to access this chip.
5073# $_[1]: Address
5074# Returns: undef if not detected, (8) if detected.
5075# Registers used:
5076#   0x00-0x02: Identification ('H','E','R')
5077sub fscher_detect
5078{
5079  my ($file,$addr) = @_;
5080  # check the first 3 registers
5081  if (i2c_smbus_read_byte_data($file,0x00) != 0x48) {
5082        return;
5083  }
5084  if (i2c_smbus_read_byte_data($file,0x01) != 0x45) {
5085        return;
5086  }
5087  if (i2c_smbus_read_byte_data($file,0x02) != 0x52) {
5088        return;
5089  }
5090  return (8);
5091}
5092
5093# $_[0]: A reference to the file descriptor to access this chip.
5094# $_[1]: Address
5095# Returns: undef if not detected, (8) if detected.
5096# Registers used:
5097#   0x00-0x02: Identification ('H','M','D')
5098sub fschmd_detect
5099{
5100  my ($file,$addr) = @_;
5101  # check the first 3 registers
5102  if (i2c_smbus_read_byte_data($file,0x00) != 0x48) {
5103        return;
5104  }
5105  if (i2c_smbus_read_byte_data($file,0x01) != 0x4D) {
5106        return;
5107  }
5108  if (i2c_smbus_read_byte_data($file,0x02) != 0x44) {
5109        return;
5110  }
5111  return (8);
5112}
5113
5114# $_[0]: A reference to the file descriptor to access this chip.
5115# $_[1]: Address
5116# Returns: undef if not detected, (8) if detected.
5117# Registers used:
5118#   0x00-0x02: Identification ('H','R','C')
5119sub fschrc_detect
5120{
5121  my ($file,$addr) = @_;
5122  # check the first 3 registers
5123  if (i2c_smbus_read_byte_data($file,0x00) != 0x48) {
5124        return;
5125  }
5126  if (i2c_smbus_read_byte_data($file,0x01) != 0x52) {
5127        return;
5128  }
5129  if (i2c_smbus_read_byte_data($file,0x02) != 0x43) {
5130        return;
5131  }
5132  return (8);
5133}
5134
5135# $_[0]: A reference to the file descriptor to access this chip.
5136# $_[1]: Address (unused)
5137# Returns: undef if not detected, 5 if detected.
5138# Registers used:
5139#   0x3E: Manufacturer ID
5140#   0x3F: Version/Stepping
5141sub lm93_detect
5142{
5143  my $file = shift;
5144  return unless i2c_smbus_read_byte_data($file, 0x3E) == 0x01
5145            and i2c_smbus_read_byte_data($file, 0x3F) == 0x73;
5146  return 5;
5147}
5148
5149# $_[0]: A reference to the file descriptor to access this chip.
5150# $_[1]: Address
5151# Returns: undef if not detected, (7) if detected.
5152# Registers used:
5153#   0x3F: Revision ID
5154#   0x48: Address
5155#   0x4A, 0x4B, 0x4F, 0x57, 0x58: Reserved bits.
5156# We do not use 0x49's reserved bits on purpose. The register is named
5157# "VID4/Device ID" so it is doubtful bits 7-1 are really unused.
5158sub m5879_detect
5159{
5160  my ($file, $addr) = @_;
5161
5162  return
5163    unless i2c_smbus_read_byte_data($file, 0x3F) == 0x01;
5164 
5165  return
5166    unless i2c_smbus_read_byte_data($file, 0x48) == $addr;
5167 
5168  return
5169    unless (i2c_smbus_read_byte_data($file, 0x4A) & 0x06) == 0
5170       and (i2c_smbus_read_byte_data($file, 0x4B) & 0xFC) == 0
5171       and (i2c_smbus_read_byte_data($file, 0x4F) & 0xFC) == 0
5172       and (i2c_smbus_read_byte_data($file, 0x57) & 0xFE) == 0
5173       and (i2c_smbus_read_byte_data($file, 0x58) & 0xEF) == 0;
5174
5175  return (7);
5176}
5177
5178# $_[0]: A reference to the file descriptor to access this chip.
5179# $_[1]: Address
5180# Returns: undef if not detected, 5 or 6 if detected.
5181# Registers used:
5182#   0x3E: Manufacturer ID
5183#   0x3F: Version/Stepping
5184#   0x47: VID (3 reserved bits)
5185#   0x49: VID4 (7 reserved bits)
5186sub smsc47m192_detect
5187{
5188  my ($file, $addr) = @_;
5189  return unless i2c_smbus_read_byte_data($file, 0x3E) == 0x55
5190           and (i2c_smbus_read_byte_data($file, 0x3F) & 0xF0) == 0x20
5191           and (i2c_smbus_read_byte_data($file, 0x47) & 0x70) == 0x00
5192           and (i2c_smbus_read_byte_data($file, 0x49) & 0xFE) == 0x80;
5193  return ($addr == 0x2d ? 6 : 5);
5194}
5195
5196# $_[0]: Chip to detect
5197#        (1 = DME1737, 2 = SCH5027)
5198# $_[1]: A reference to the file descriptor to access this chip.
5199# $_[2]: Address
5200# Returns: undef if not detected, 5 or 6 if detected.
5201# Registers used:
5202#   0x3E: Manufacturer ID
5203#   0x3F: Version/Stepping
5204#   0x73: Read-only test register (4 test bits)
5205#   0x8A: Read-only test register (7 test bits)
5206#   0xBA: Read-only test register (8 test bits)
5207sub dme1737_detect
5208{
5209  my ($chip, $file, $addr) = @_;
5210  my $vendor = i2c_smbus_read_byte_data($file, 0x3E);
5211  my $verstep = i2c_smbus_read_byte_data($file, 0x3F);
5212
5213  return unless $vendor == 0x5C; # SMSC
5214
5215  if ($chip == 1) { # DME1737
5216      return unless ($verstep & 0xF8) == 0x88 and
5217          (i2c_smbus_read_byte_data($file, 0x73) & 0x0F) == 0x09 and
5218          (i2c_smbus_read_byte_data($file, 0x8A) & 0x7F) == 0x4D;
5219  } elsif ($chip == 2) { # SCH5027
5220      return unless $verstep >= 0x69 and $verstep <= 0x6F and
5221          i2c_smbus_read_byte_data($file, 0xBA) == 0x0F;
5222  }
5223
5224  return ($addr == 0x2e ? 6 : 5);
5225}
5226
5227# $_[0]: Chip to detect
5228#   (1 = F75111R/RG/N, 2 = F75121R/F75122R/RG, 3 = F75373S/SG,
5229#    4 = F75375S/SP, 5 = F75387SG/RG, 6 = F75383M/S/F75384M/S,
5230#    7 = custom power control IC)
5231# $_[1]: A reference to the file descriptor to access this chip.
5232# $_[2]: Address (unused)
5233# Returns: undef if not detected, 7 if detected.
5234# Registers used:
5235#   0x5A-0x5B: Chip ID
5236#   0x5D-0x5E: Vendor ID
5237sub fintek_detect
5238{
5239  my ($chip, $file, $addr) = @_;
5240  my $chipid = (i2c_smbus_read_byte_data($file, 0x5A) << 8)
5241             | i2c_smbus_read_byte_data($file, 0x5B);
5242  my $vendid = (i2c_smbus_read_byte_data($file, 0x5D) << 8)
5243             | i2c_smbus_read_byte_data($file, 0x5E);
5244
5245  return unless $vendid == 0x1934; # Fintek ID
5246
5247  if ($chip == 1) { # F75111R/RG/N
5248    return unless $chipid == 0x0300;
5249  } elsif ($chip == 2) { # F75121R/F75122R/RG
5250    return unless $chipid == 0x0301;
5251  } elsif ($chip == 3) { # F75373S/SG
5252    return unless $chipid == 0x0204;
5253  } elsif ($chip == 4) { # F75375S/SP
5254    return unless $chipid == 0x0306;
5255  } elsif ($chip == 5) { # F75387SG/RG
5256    return unless $chipid == 0x0410;
5257  } elsif ($chip == 6) { # F75383M/S/F75384M/S
5258    # The datasheet has 0x0303, but Fintek say 0x0413 is also possible
5259    return unless $chipid == 0x0303 || $chipid == 0x0413;
5260  } elsif ($chip == 7) { # custom power control IC
5261    return unless $chipid == 0x0302;
5262  }
5263
5264  return 7;
5265}
5266
5267# This checks for non-FFFF values for temperature, voltage, and current.
5268# The address (0x0b) is specified by the SMBus standard so it's likely
5269# that this really is a smart battery.
5270# $_[0]: A reference to the file descriptor to access this chip.
5271# $_[1]: Address
5272# Returns: 5
5273sub smartbatt_detect
5274{
5275  my ($file,$addr) = @_;
5276  # check some registers
5277  if (i2c_smbus_read_word_data($file,0x08) == 0xffff) {
5278        return;
5279  }
5280  if (i2c_smbus_read_word_data($file,0x09) == 0xffff) {
5281        return;
5282  }
5283  if (i2c_smbus_read_word_data($file,0x0a) == 0xffff) {
5284        return;
5285  }
5286  return (5);
5287}
5288
5289# Returns: 4
5290# These are simple detectors that only look for a register at the
5291# standard location. No writes are performed.
5292# For KCS, use the STATUS register. For SMIC, use the FLAGS register.
5293sub ipmi_kcs_detect
5294{
5295  return if inb (0x0ca3) == 0xff;
5296  return (4);
5297}
5298
5299sub ipmi_smic_detect
5300{
5301  return if inb (0x0cab) == 0xff;
5302  return (4);
5303}
5304
5305# $_[0]: Chip to detect (0 = W83L784R/AR/G, 1 = W83L785R/G,
5306#                        2 = W83L786NR/NG/R/G)
5307# $_[1]: A reference to the file descriptor to access this chip.
5308# $_[2]: Address
5309# Returns: undef if not detected, 6 or 8 if detected
5310# Registers used:
5311#   0x40: Configuration
5312#   0x4a: Full I2C Address (W83L784R only)
5313#   0x4b: I2C addresses of emulated LM75 chips (W83L784R only)
5314#   0x4c: Winbond Vendor ID (Low Byte)
5315#   0x4d: Winbond Vendor ID (High Byte)
5316#   0x4e: Chip ID
5317sub w83l784r_detect
5318{
5319  my ($reg,@res);
5320  my ($chip,$file,$addr) = @_;
5321
5322  return unless (i2c_smbus_read_byte_data($file,0x40) & 0x80) == 0x00;
5323  return if $chip == 0
5324    and i2c_smbus_read_byte_data($file,0x4a) != $addr;
5325  return unless i2c_smbus_read_byte_data($file,0x4c) == 0xa3;
5326  return unless i2c_smbus_read_byte_data($file,0x4d) == 0x5c;
5327
5328  $reg = i2c_smbus_read_byte_data($file, 0x4e);
5329  return if $chip == 0 and $reg != 0x50;
5330  return if $chip == 1 and $reg != 0x60;
5331  return if $chip == 2 and $reg != 0x80;
5332
5333  return 6 if $chip != 0; # No subclients
5334 
5335  @res = (8);
5336  $reg = i2c_smbus_read_byte_data($file, 0x4b);
5337  push @res, ($reg & 0x07) + 0x48 unless $reg & 0x08 ;
5338  push @res, (($reg & 0x70) >> 4) + 0x48 unless $reg & 0x80;
5339  return @res;
5340}
5341
5342# $_[0]: Chip to detect (0 = W83L785TS-S)
5343# $_[1]: A reference to the file descriptor to access this chip.
5344# $_[2]: Address
5345# Returns: undef if not detected, 8 if detected
5346# Registers used:
5347#   0x4C-4E: Mfr and Chip ID
5348sub w83l785ts_detect
5349{
5350  my ($chip,$file,$addr) = @_;
5351  return unless i2c_smbus_read_byte_data($file,0x4c) == 0xa3;
5352  return unless i2c_smbus_read_byte_data($file,0x4d) == 0x5c;
5353  return unless i2c_smbus_read_byte_data($file,0x4e) == 0x70;
5354  return (8);
5355}
5356
5357# $_[0]: Chip to detect. Always zero for now, but available for future use
5358#        if somebody finds a way to distinguish MAX6650 and MAX6651.
5359# $_[1]: A reference to the file descriptor to access this chip.
5360# $_[2]: Address
5361# Returns: undef if not detected, 3 if detected.
5362#
5363# The max6650 has no device ID register. However, a few registers have
5364# spare bits, which are documented as being always zero on read. We read
5365# all of these registers check the spare bits. Any non-zero means this
5366# is not a max6650/1.
5367#
5368# The always zero bits are:
5369#   configuration byte register (0x02) - top 2 bits
5370#   gpio status register (0x14) - top 3 bits
5371#   alarm enable register (0x08) - top 3 bits
5372#   alarm status register (0x0A) - top 3 bits
5373#   tachometer count time register (0x16) - top 6 bits
5374# Additionally, not all values are possible for lower 3 bits of
5375# the configuration register.
5376sub max6650_detect
5377{
5378  my ($chip, $file) = @_;
5379
5380  my $conf = i2c_smbus_read_byte_data($file,0x02);
5381 
5382  return if i2c_smbus_read_byte_data($file,0x16) & 0xFC;
5383  return if i2c_smbus_read_byte_data($file,0x0A) & 0xE0;
5384  return if i2c_smbus_read_byte_data($file,0x08) & 0xE0;
5385  return if i2c_smbus_read_byte_data($file,0x14) & 0xE0;
5386  return if ($conf & 0xC0) or ($conf & 0x07) > 4;
5387
5388  return 3;
5389}
5390
5391# $_[0]: Chip to detect. Always zero.
5392# $_[1]: A reference to the file descriptor to access this chip.
5393# $_[2]: Address.
5394#
5395# Returns: undef if not detected, 6 if detected.
5396sub max6655_detect
5397{
5398  my ($chip, $file, $addr) = @_;
5399
5400  # checking RDID (Device ID)
5401  return unless i2c_smbus_read_byte_data($file, 0xfe) == 0x0a;
5402  # checking RDRV (Manufacturer ID)
5403  return unless i2c_smbus_read_byte_data($file, 0xff) == 0x4d;
5404  # checking unused bits (conversion rate, extended temperature)
5405  return unless i2c_smbus_read_byte_data($file, 0x04) & 0xf8;
5406  return unless i2c_smbus_read_byte_data($file, 0x10) & 0x1f;
5407  return unless i2c_smbus_read_byte_data($file, 0x11) & 0x1f;
5408  return unless i2c_smbus_read_byte_data($file, 0x12) & 0x1f;
5409
5410  return 6;
5411}
5412
5413# $_[0]: Chip to detect (0 = VT1211)
5414# $_[1]: A reference to the file descriptor to access this chip.
5415# $_[2]: Address
5416#
5417# This isn't very good detection.
5418# Verify the i2c address, and the stepping ID (which is 0xb0 on
5419# my chip but could be different for others...
5420#
5421sub vt1211_i2c_detect
5422{
5423  my ($chip,$file,$addr) = @_;
5424  return unless (i2c_smbus_read_byte_data($file,0x48) & 0x7f) == $addr;
5425  return unless i2c_smbus_read_byte_data($file,0x3f) == 0xb0;
5426  return 2;
5427}
5428
5429# $_[0]: Chip to detect (0 = VT1211)
5430# $_[1]: ISA address
5431# $_[2]: I2C file handle
5432# $_[3]: I2C address
5433sub vt1211_alias_detect
5434{
5435  my ($chip,$isa_addr,$file,$i2c_addr) = @_;
5436  my $i;
5437  return 0 unless (inb($isa_addr + 0x48) & 0x7f) == $i2c_addr;
5438  return 0 unless (i2c_smbus_read_byte_data($file,0x48) & 0x7f) == $i2c_addr;
5439  for ($i = 0x2b; $i <= 0x3d; $i ++) {
5440    return 0 unless inb($isa_addr + $i) == i2c_smbus_read_byte_data($file,$i);
5441  }
5442  return 1;
5443}
5444
5445
5446######################
5447# PCI CHIP DETECTION #
5448######################
5449
5450# Returns: undef if not detected, (7) or (9) if detected.
5451# The address is encoded in PCI space. We could decode it and print it.
5452# For Linux 2.4 we should probably check for invalid matches (SiS645).
5453sub sis5595_pci_detect
5454{
5455        return unless exists $pci_list{'1039:0008'};
5456        return (kernel_version_at_least(2, 6, 0) ? 9 : 7);
5457}
5458
5459# Returns: undef if not detected, (9) if detected.
5460# The address is encoded in PCI space. We could decode it and print it.
5461sub via686a_pci_detect
5462{
5463        return unless exists $pci_list{'1106:3057'};
5464        return 9;
5465}
5466
5467# Returns: undef if not detected, (9) if detected.
5468# The address is encoded in PCI space. We could decode it and print it.
5469sub via8231_pci_detect
5470{
5471        return unless exists $pci_list{'1106:8235'};
5472        return 9;
5473}
5474
5475# Returns: undef if not detected, (9) if detected.
5476sub k8temp_pci_detect
5477{
5478        return unless exists $pci_list{'1022:1103'};
5479        return 9;
5480}
5481
5482sub k10temp_pci_detect
5483{
5484        return unless exists $pci_list{'1022:1203'};
5485        return 9;
5486}
5487
5488# Returns: undef if not detected, (9) if detected.
5489# the device 0xa620 should not be visible on host PCI bus, gateway
5490# must be used
5491sub intel_amb_detect
5492{
5493        if ((exists $pci_list{'8086:a620'}) ||
5494           (exists $pci_list{'8086:25f0'})) {
5495                return 9;
5496        }
5497        return;
5498}
5499
5500# Returns: undef if not detected, (9) if detected.
5501sub coretemp_detect
5502{
5503        my $probecpu;
5504        foreach $probecpu (@cpu) {
5505                if ($probecpu->{'vendor_id'} eq 'GenuineIntel' && 
5506                                $probecpu->{'cpu family'} == 6 &&
5507                                ($probecpu->{'model'} == 14 ||
5508                                 $probecpu->{'model'} == 15 ||
5509                                 $probecpu->{'model'} == 0x16 ||
5510                                 $probecpu->{'model'} == 0x17)) {
5511                        return 9;
5512                }
5513        }
5514        return;
5515}
5516
5517################
5518# MAIN PROGRAM #
5519################
5520
5521# $_[0]: reference to a list of chip hashes
5522sub print_chips_report 
5523{
5524  my ($listref) = @_;
5525  my $data;
5526 
5527  foreach $data (@$listref) {
5528    my $is_i2c = exists $data->{i2c_addr};
5529    my $is_isa = exists $data->{isa_addr};
5530    print "  * ";
5531    if ($is_i2c) {
5532      printf "Bus `%s'\n", $data->{i2c_adap};
5533      printf "    Busdriver `%s', I2C address 0x%02x", 
5534             $data->{i2c_driver}, $data->{i2c_addr};
5535      if (exists $data->{i2c_sub_addrs}) {
5536        print " (and";
5537        my $sub_addr;
5538        foreach $sub_addr (@{$data->{i2c_sub_addrs}}) {
5539          printf " 0x%02x",$sub_addr;
5540        }
5541        print ")"
5542      }
5543      print "\n    ";
5544    }
5545    if ($is_isa) {
5546      print "ISA bus";
5547      if ($data->{isa_addr}) {
5548        printf ", address 0x%x", $data->{isa_addr};
5549      }
5550      print " (Busdriver `i2c-isa')"
5551        unless kernel_version_at_least(2, 6, 18);
5552      print "\n    ";
5553    }
5554    printf "Chip `%s' (confidence: %d)\n",
5555           $data->{chipname},  $data->{conf};
5556  }
5557}
5558
5559# $_[0]: 1 if ISA bus is prefered, 0 for SMBus
5560# We build here an array adapters, indexed on the number the adapter has
5561# at this moment (we assume only loaded adapters are interesting at all;
5562# everything that got scanned also got loaded). Each entry is a reference
5563# to a hash containing:
5564#  driver: Name of the adapter driver
5565#  nr_now: Number of the bus now
5566#  nr_later: Number of the bus when the modprobes are done (not included if the
5567#        driver should not be loaded)
5568# A second array, called
5569sub generate_modprobes
5570{
5571  my ($prefer_isa) = @_;
5572
5573  my ($chip,$detection,$nr,$i,@optionlist,@probelist,$driver,$isa,$adap);
5574  my $ipmi = 0;
5575  my $modprobes = "";
5576  my $configfile;
5577
5578  # Collect all adapters used
5579  $nr = 0;
5580  $isa = 0;
5581  foreach $chip (@chips_detected) {
5582    foreach $detection (@{$chip->{detected}}) {
5583      # If there is more than one bus detected by a driver, they are
5584      # still all added. So we number them in the correct order
5585      if (exists $detection->{i2c_driver} and
5586          not exists $i2c_adapters[$detection->{i2c_devnr}]->{nr_later} and 
5587          not (exists $detection->{isa_addr} and $prefer_isa)) {
5588         foreach $adap (@i2c_adapters) {
5589           next unless exists $adap->{driver};
5590           $adap->{nr_later} = $nr++ if $adap->{driver} eq $detection->{i2c_driver};
5591         }
5592      }
5593      if (exists $detection->{isa_addr} and
5594          not (exists $detection->{i2c_driver} and not $prefer_isa)) {
5595           $isa=1;
5596      }
5597      if ($chip->{driver} eq "bmcsensors" || 
5598          $chip->{driver} eq "ipmisensors") {
5599           $ipmi = 1;
5600      }
5601    }
5602  }
5603
5604  $modprobes .= "# I2C adapter drivers\n" if $nr;
5605  for ($i = 0; $i < $nr; $i++) {
5606    foreach $adap (@i2c_adapters) {
5607      next unless exists $adap->{nr_later} and $adap->{nr_later} == $i;
5608      if ($adap->{driver} eq "UNKNOWN") {
5609        $modprobes .= "# modprobe unknown adapter ".$adap->{name}."\n";
5610      } elsif ($adap->{driver} eq "DISABLED") {
5611        $modprobes .= "# modprobe disabled adapter ".$adap->{name}."\n";
5612      } elsif ($adap->{driver} eq "to-be-written") {
5613        $modprobes .= "# no driver available for adapter ".$adap->{name}."\n";
5614      } else {
5615        $modprobes .= "modprobe $adap->{driver}\n"
5616          unless $modprobes =~ /modprobe $adap->{driver}\n/;
5617      }
5618      last;
5619    }
5620  }
5621  # i2c-isa is loaded automatically (as a dependency) since 2.6.14,
5622  # and will soon be gone.
5623  $modprobes .= "modprobe i2c-isa\n" if ($isa && !kernel_version_at_least(2, 6, 18));
5624  if ($ipmi) {
5625    $modprobes .= "# You must also install and load the IPMI modules\n";
5626    if (kernel_version_at_least(2, 6, 0)) {
5627      $modprobes .= "modprobe ipmi-si\n";
5628    } else {
5629      $modprobes .= "modprobe i2c-ipmi\n";
5630    }
5631  }
5632
5633  # Now determine the chip probe lines
5634  $modprobes .= "# Chip drivers\n";
5635  foreach $chip (@chips_detected) {
5636    next if not @{$chip->{detected}};
5637    if ($chip->{driver} eq "to-be-written") {
5638      $modprobes .= "# no driver for $chip->{detected}[0]{chipname} yet\n";
5639    } else {
5640       # need the * for 2.4 kernels, won't necessarily be an exact match
5641       open(local *INPUTFILE, "modprobe -l $chip->{driver}\\* 2>/dev/null |");
5642       local $_;
5643       my $modulefound = 0;
5644       while (<INPUTFILE>) {
5645         if(m@/@) {
5646           $modulefound = 1;
5647           last;
5648         }
5649       }
5650       close INPUTFILE;
5651       #check return value from modprobe in case modprobe -l isn't supported
5652       if((($? >> 8) == 0) && ! $modulefound) {
5653         $modprobes .= "# Warning: the required module $chip->{driver} is not currently installed\n".
5654                       "# on your system. For status of 2.6 kernel ports check\n".
5655                       "# http://www.lm-sensors.org/wiki/Devices. If driver is built\n".
5656                       "# into the kernel, or unavailable, comment out the following line.\n";
5657       }
5658       $modprobes .= "modprobe $chip->{driver}\n";
5659    }
5660
5661    # Handle misdetects
5662    foreach $detection (@{$chip->{misdetected}}) {
5663      push @optionlist, $i2c_adapters[$detection->{i2c_devnr}]->{nr_later},
5664                       $detection->{i2c_addr}
5665           if exists $detection->{i2c_addr} and
5666              exists $i2c_adapters[$detection->{i2c_devnr}]->{nr_later};
5667      push @optionlist, -1, $detection->{isa_addr}
5668           if exists $detection->{isa_addr} and $isa;
5669    }
5670
5671    # Handle aliases
5672    foreach $detection (@{$chip->{detected}}) {
5673      if (exists $detection->{i2c_driver} and 
5674          exists $detection->{isa_addr} and
5675          exists $i2c_adapters[$detection->{i2c_devnr}]->{nr_later} and
5676          $isa) {
5677        if ($prefer_isa) {
5678          push @optionlist, $i2c_adapters[$detection->{i2c_devnr}]->{nr_later},
5679                           $detection->{i2c_addr};
5680        } else {
5681          push @optionlist, -1, $detection->{isa_addr}
5682        }
5683      }
5684    }
5685
5686    next if not (@probelist or @optionlist);
5687    $configfile = "# hwmon module options\n" unless defined $configfile;
5688    $configfile .= "options $chip->{driver}";
5689    $configfile .= sprintf " ignore=%d,0x%02x",shift @optionlist, 
5690                                               shift @optionlist
5691                  if @optionlist;
5692    $configfile .= sprintf ",%d,0x%02x",shift @optionlist, shift @optionlist
5693                  while @optionlist;
5694    $configfile .= sprintf " probe=%d,0x%02x",shift @probelist,
5695                                              shift @probelist
5696                  if @probelist;
5697    $configfile .= sprintf ",%d,0x%02x",shift @probelist, shift @probelist
5698                  while @probelist;
5699    $configfile .= "\n";
5700  }
5701
5702  return ($modprobes,$configfile);
5703 
5704}
5705
5706sub main
5707{
5708  my (@adapters,$res,$did_adapter_detection,$adapter);
5709
5710  # We won't go very far if not root
5711  unless ($> == 0) {
5712    print "You need to be root to run this script.\n";
5713    exit -1;
5714  }
5715
5716  if (-x "/sbin/service" && -f "/etc/init.d/lm_sensors" &&
5717      -f "/var/lock/subsys/lm_sensors") {
5718    system("/sbin/service", "lm_sensors", "stop");
5719  }
5720
5721  initialize_kernel_version();
5722  initialize_conf;
5723  initialize_proc_pci;
5724  initialize_modules_list;
5725  # make sure any special case chips are added to the chip_ids list before
5726  # making the support modules list
5727  chip_special_cases();
5728  initialize_modules_supported;
5729  initialize_cpu_list();
5730
5731  print "# sensors-detect revision $revision\n\n";
5732
5733  print "This program will help you determine which kernel modules you need\n",
5734        "to load to use lm_sensors most effectively. It is generally safe\n",
5735        "and recommended to accept the default answers to all questions,\n",
5736        "unless you know what you're doing.\n";
5737  print "You need to have i2c and lm_sensors installed before running this\n",
5738        "program.\n"
5739    unless kernel_version_at_least(2, 6, 0);
5740  print "\n";
5741
5742  print "We can start with probing for (PCI) I2C or SMBus adapters.\n";
5743  print "Do you want to probe now? (YES/no): ";
5744  @adapters = adapter_pci_detection
5745                        if ($did_adapter_detection = not <STDIN> =~ /\s*[Nn]/);
5746  print "\n";
5747
5748  if (not $did_adapter_detection) {
5749    print "As you skipped adapter detection, we will only scan already loaded\n".
5750          "adapter modules.\n";
5751  } else {
5752    print "We will now try to load each adapter module in turn.\n"
5753      if (@adapters);
5754    foreach $adapter (@adapters) {
5755      next if $adapter eq "DISABLED";
5756      next if $adapter eq "to-be-tested";
5757      if (exists($modules_list{$adapter})) {
5758        print "Module `$adapter' already loaded.\n";
5759      } else {
5760        print "Load `$adapter' (say NO if built into your kernel)? (YES/no): ";
5761        unless (<STDIN> =~ /^\s*[Nn]/) {
5762          if (system ("modprobe", $adapter)) {
5763            print "Loading failed... skipping.\n";
5764          } else {
5765            print "Module loaded successfully.\n";
5766          }
5767        }
5768      }
5769    }
5770  }
5771
5772  print "If you have undetectable or unsupported I2C/SMBus adapters, you can have\n".
5773        "them scanned by manually loading the modules before running this script.\n\n";
5774  initialize_i2c_adapters_list();
5775
5776  if (!exists($modules_list{"i2c-dev"})
5777   && !(defined $sysfs_root && -e "$sysfs_root/class/i2c-dev")) {
5778    print "To continue, we need module `i2c-dev' to be loaded.\n";
5779    print "If it is built-in into your kernel, you can safely skip this.\n"
5780      unless kernel_version_at_least(2, 6, 0);
5781    print "Do you want to load `i2c-dev' now? (YES/no): ";
5782    if (<STDIN> =~ /^\s*n/i) {
5783      print "Well, you will know best.\n";
5784    } elsif (system "modprobe", "i2c-dev") {
5785      print "Loading failed, expect problems later on.\n";
5786    } else {
5787      print "Module loaded successfully.\n";
5788    }
5789    print "\n";
5790  }
5791
5792  $i2c_addresses_to_scan = i2c_addresses_to_scan();
5793
5794  print "We are now going to do the I2C/SMBus adapter probings. Some chips may\n",
5795        "be double detected; we choose the one with the highest confidence\n",
5796        "value in that case.\n",
5797        "If you found that the adapter hung after probing a certain address,\n",
5798        "you can specify that address to remain unprobed.\n";
5799
5800  my ($inp,@not_to_scan,$inp2);
5801  for (my $dev_nr = 0; $dev_nr < @i2c_adapters; $dev_nr++) {
5802    next unless exists $i2c_adapters[$dev_nr];
5803    my $adap = $i2c_adapters[$dev_nr]->{'name'};
5804    print "\n";
5805    print "Next adapter: $adap (i2c-$dev_nr)\n";
5806    print "Do you want to scan it? (YES/no/selectively): ";
5807   
5808    $inp = <STDIN>;
5809    if ($inp =~ /^\s*[Ss]/) {
5810      print "Please enter one or more addresses not to scan. Separate them ",
5811            "with comma's.\n",
5812            "You can specify a range by using dashes. Addresses may be ",
5813            "decimal (like 54)\n",
5814            "or hexadecimal (like 0x33).\n",
5815            "Addresses: ";
5816      $inp2 = <STDIN>;
5817      chop $inp2;
5818      @not_to_scan = parse_not_to_scan 0,0x7f,$inp2;
5819    }
5820    scan_adapter $dev_nr, $adap, $i2c_adapters[$dev_nr]->{'drive