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

Revision 4144, 165.8 KB (checked in by khali, 7 years ago)

sensors-detect: Add generic Super-I/O logical device detection.
For families where it makes sense (ITE, Winbond, Fintek), when we have
an unknown Super-I/O, we scan all logical devices in search of one
with the typical address for hardware monitoring (0x290). If we find
it, we let the user know there are probably sensors in the chip.

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