root/i2c-tools/trunk/eeprom/decode-vaio

Revision 5172, 5.5 kB (checked in by khali, 8 months ago)

Remove history, it belongs to SVN.
Don't tell people to contact me, they'll find out by themselves if
they want to.
Make the header text shorter.
Bump version to 1.6.

  • 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 # Copyright (C) 2002-2008  Jean Delvare <khali@linux-fr.org>
4 #
5 #    This program is free software; you can redistribute it and/or modify
6 #    it under the terms of the GNU General Public License as published by
7 #    the Free Software Foundation; either version 2 of the License, or
8 #    (at your option) any later version.
9 #
10 #    This program is distributed in the hope that it will be useful,
11 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 #    GNU General Public License for more details.
14 #
15 #    You should have received a copy of the GNU General Public License
16 #    along with this program; if not, write to the Free Software
17 #    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 #    MA 02110-1301 USA.
19 #
20 # EEPROM data decoding for Sony Vaio laptops.
21 #
22 # The eeprom driver must be loaded. For kernels older than 2.6.0, the
23 # eeprom driver can be found in the lm-sensors package.
24 #
25 # Please note that this is a guess-only work.  Sony support refused to help
26 # me, so if someone can provide information, please contact me.
27 # My knowledge is summarized on this page:
28 # http://khali.linux-fr.org/vaio/eeprom.html
29 #
30 # It seems that if present, the EEPROM is always at 0x57.
31 #
32 # Models tested so far:
33 #   PCG-F403     : No EEPROM
34 #   PCG-F707     : No EEPROM
35 #   PCG-GR114EK  : OK
36 #   PCG-GR114SK  : OK
37 #   PCG-GR214EP  : OK
38 #   PCG-GRT955MP : OK
39 #   PCG-GRX316G  : OK
40 #   PCG-GRX570   : OK
41 #   PCG-GRX600K  : OK
42 #   PCG-U1       : OK
43 #   PCG-Z600LEK  : No EEPROM
44 #   PCG-Z600NE   : No EEPROM
45 #   VGN-S260     : OK
46 #   VGN-S4M/S    : OK
47 #   VGN-TZ11MN/N : OK
48 #
49 # Thanks to Werner Heuser, Carsten Blume, Christian Gennerat, Joe Wreschnig,
50 # Xavier Roche, Sebastien Lefevre, Lars Heer, Steve Dobson, Kent Hunt,
51 # Timo Hoenig and others for their precious help.
52
53
54 use strict;
55 use Fcntl qw(:DEFAULT :seek);
56 use vars qw($sysfs $found);
57
58 use constant VERSION    => "1.6";
59 use constant ONLYROOT   => "Readable only by root";
60
61 sub print_item
62 {
63         my ($label,$value) = @_;
64        
65         printf("\%16s : \%s\n",$label,$value);
66 }
67
68 # Abstract reads so that other functions don't have to care wether
69 # we need to use procfs or sysfs
70 sub read_eeprom_bytes
71 {
72         my ($bus, $addr, $offset, $length) = @_;
73         my $filename;
74        
75         if ($sysfs)
76         {
77                 $filename = "/sys/bus/i2c/devices/$bus-00$addr/eeprom";
78                 sysopen(FH, $filename, O_RDONLY)
79                         or die "Can't open $filename";
80                 sysseek(FH, $offset, SEEK_SET)
81                         or die "Can't seek in $filename";
82
83                 my ($r, $bytes);
84                 $bytes = '';
85                 $offset = 0;
86                 while($length)
87                 {
88                         $r = sysread(FH, $bytes, $length, $offset);
89                         die "Can't read $filename"
90                                 unless defined($r);
91                         die "Unexpected EOF in $filename"
92                                 unless $r;
93                         $offset += $r;
94                         $length -= $r;
95                 }
96                 close(FH);
97                
98                 return $bytes;
99         }
100         else
101         {
102                 my $base = $offset & 0xf0;
103                 $offset -= $base;
104                 my $values = '';
105                 my $remains = $length + $offset;
106                
107                 # Get all lines in a single string
108                 while ($remains > 0)
109                 {
110                         $filename = "/proc/sys/dev/sensors/eeprom-i2c-$bus-$addr/"
111                                   . sprintf('%02x', $base);
112                         open(FH, $filename)
113                                 or die "Can't open $filename";
114                         $values .= <FH>;
115                         close(FH);
116                         $remains -= 16;
117                         $base += 16;
118                 }
119                
120                 # Store the useful part in an array
121                 my @bytes = split(/[ \n]/, $values);
122                 @bytes = @bytes[$offset..$offset+$length-1];
123
124                 # Back to a binary string
125                 return pack('C*', @bytes);
126         }
127 }
128
129 sub decode_string
130 {
131         my ($bus, $addr, $offset, $length) = @_;
132
133         my $string = read_eeprom_bytes($bus, $addr, $offset, $length);
134         $string =~ s/\x00.*$//;
135        
136         return($string);
137 }
138
139 sub decode_hexa
140 {
141         my ($bus, $addr, $offset, $length) = @_;
142
143         my @bytes = unpack('C*', read_eeprom_bytes($bus, $addr, $offset, $length));
144         my $string='';
145
146         for(my $i=0;$i<$length;$i++)
147         {
148                 $string.=sprintf('%02X', shift(@bytes));
149         }
150
151         return($string);
152 }
153
154 sub decode_uuid
155 {
156         my ($bus,$addr,$base) = @_;
157
158         my @bytes = unpack('C16', read_eeprom_bytes($bus, $addr, $base, 16));
159         my $string='';
160
161         for(my $i=0;$i<16;$i++)
162         {
163                 $string.=sprintf('%02x',shift(@bytes));
164                 if(($i==3)||($i==5)||($i==7)||($i==9))
165                 {
166                         $string.='-';
167                 }
168         }
169
170         if ($string eq '00000000-0000-0000-0000-000000000000')
171         {
172                 return(ONLYROOT);
173         }
174         else
175         {
176                 return($string);
177         }
178 }
179
180 sub vaio_decode
181 {
182         my ($bus,$addr) = @_;
183        
184         my $name = decode_string($bus, $addr, 128, 32);
185         # Simple heuristic to skip false positives
186         return 0 unless $name =~ m/^[A-Z-]{4}/;
187
188         print_item('Machine Name', $name);
189         my $serial = decode_string($bus, $addr, 192, 32);
190         print_item('Serial Number', $serial ? $serial : ONLYROOT);
191         print_item('UUID', decode_uuid($bus, $addr, 16));
192         my $revision = decode_string($bus, $addr, 160, 10);
193         print_item(length($revision) > 2 ? 'Service Tag' : 'Revision',
194                    $revision);
195         print_item('Asset Tag', decode_string($bus, $addr, 170, 4).
196                                 decode_hexa($bus, $addr, 174, 12));
197         print_item('OEM Data', decode_string($bus, $addr, 32, 16));
198         print_item('Timestamp', decode_string($bus, $addr, 224, 18));
199         return 1;
200 }
201
202 BEGIN
203 {
204         print("# Sony Vaio EEPROM Decoder version ".VERSION." by Jean Delvare\n\n");
205 }
206
207 END
208 {
209         print("\n");
210 }
211
212 for (my $i = 0, $found=0; $i <= 4 && !$found; $i++)
213 {
214         if (-r "/sys/bus/i2c/devices/$i-0057/eeprom")
215         {
216                 $sysfs = 1;
217                 $found += vaio_decode($i, '57');
218         }
219         elsif (-r "/proc/sys/dev/sensors/eeprom-i2c-$i-57")
220         {
221                 if (-r "/proc/sys/dev/sensors/eeprom-i2c-$i-57/data0-15")
222                 {
223                         print("Deprecated old interface found.  Please upgrade to lm_sensors 2.6.3 or greater.");
224                         exit;
225                 }
226                 else
227                 {
228                         $sysfs = 0;
229                         $found += vaio_decode($i, '57');
230                 }
231         }
232 }
233
234 if (!$found)
235 {
236         print("Vaio EEPROM not found.  Please make sure that the eeprom module is loaded.\n");
237 }
Note: See TracBrowser for help on using the browser.