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

Revision 4085, 166.7 KB (checked in by khali, 7 years ago)

sensors-detect: Drop the ISA IT87xxF detection. Super-I/O detection is
more reliable.

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