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

Revision 5561, 5.5 KB (checked in by khali, 20 months ago)

Strip trailing whitespace and redundant spaces.

  • 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
54use strict;
55use Fcntl qw(:DEFAULT :seek);
56use vars qw($sysfs $found);
57
58use constant VERSION    => "1.6";
59use constant ONLYROOT   => "Readable only by root";
60
61sub 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
70sub 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
129sub 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
139sub 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
154sub 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
180sub 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
202BEGIN
203{
204        print("# Sony Vaio EEPROM Decoder version ".VERSION." by Jean Delvare\n\n");
205}
206
207END
208{
209        print("\n");
210}
211
212for (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
234if (!$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.