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

Revision 3197, 159.6 KB (checked in by ruik, 8 years ago)

Change state of ATI SMBus to "to-be-tested"

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