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

Revision 4117, 167.3 KB (checked in by khali, 7 years ago)

Drop func from PCI device entries, as we don't use it anymore.

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