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

Revision 4076, 168.0 KB (checked in by khali, 7 years ago)

EEPROMs are not sensors.

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