~ubuntu-branches/ubuntu/precise/v4l-utils/precise

« back to all changes in this revision

Viewing changes to contrib/em28xx/rewrite_eeprom.pl

  • Committer: Bazaar Package Importer
  • Author(s): Gregor Jasny
  • Date: 2010-02-28 19:44:15 UTC
  • Revision ID: james.westby@ubuntu.com-20100228194415-067hdj8rvawj91zw
Tags: upstream-0.7.90
ImportĀ upstreamĀ versionĀ 0.7.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/perl -w
 
2
#
 
3
################################################################################
 
4
#  Copyright (C) 2009
 
5
#
 
6
#  Mauro Carvalho Chehab <mchehab@redhat.com>
 
7
#  Douglas Schilling Landgraf <dougsland@redhat.com>
 
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, version 2 of the License.
 
12
#
 
13
#  This program is distributed in the hope that it will be useful,
 
14
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
#  GNU General Public License for more details.
 
17
#
 
18
#  Although not very common, on a few devices, the eeprom may be erased, due to a
 
19
#  bug on a *few eeprom* chipsets that sometimes considers i2c messages to other
 
20
#  devices as being for it.
 
21
#
 
22
#  The solution for it is to reprogram the eeprom with their original contents.
 
23
#
 
24
#  Modules this script is known to work with: em28xx and saa7134
 
25
#  * Not tested against newer em28xx chipsets like the em2874 and em2884
 
26
#
 
27
########################################################
 
28
# NOTE                                                 #
 
29
################################################################################
 
30
# Since the script will try to detect the proper i2c bus address, it will only #
 
31
# work well if you have just one V4L device connected.                         #
 
32
################################################################################
 
33
#
 
34
########################################
 
35
# What do you need to run this script? #
 
36
########################################
 
37
#
 
38
# * eeprom - A dump file with the older eeprom.
 
39
#
 
40
# As example this is a dump from EMPIRE TV DUAL (310U):
 
41
#                                ^^^^^^^^^^^^^^
 
42
# shell> dmesg
 
43
#
 
44
# [11196.181543] em28xx #0: i2c eeprom 00: 1a eb 67 95 1a eb 10 e3 d0 12 5c 03 6a 22 00 00
 
45
# [11196.181559] em28xx #0: i2c eeprom 10: 00 00 04 57 4e 07 00 00 00 00 00 00 00 00 00 00
 
46
# [11196.181572] em28xx #0: i2c eeprom 20: 46 00 01 00 f0 10 01 00 00 00 00 00 5b 1e 00 00
 
47
# [11196.181585] em28xx #0: i2c eeprom 30: 00 00 20 40 20 80 02 20 01 01 00 00 00 00 00 00
 
48
# [11196.181598] em28xx #0: i2c eeprom 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 
49
# [11196.181610] em28xx #0: i2c eeprom 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 
50
# [11196.181622] em28xx #0: i2c eeprom 60: 00 00 00 00 00 00 00 00 00 00 22 03 55 00 53 00
 
51
# [11196.181635] em28xx #0: i2c eeprom 70: 42 00 20 00 32 00 38 00 38 00 31 00 20 00 44 00
 
52
# [11196.181648] em28xx #0: i2c eeprom 80: 65 00 76 00 69 00 63 00 65 00 00 00 00 00 00 00
 
53
# [11196.181660] em28xx #0: i2c eeprom 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 
54
# [11196.181673] em28xx #0: i2c eeprom a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 
55
# [11196.181685] em28xx #0: i2c eeprom b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 
56
# [11196.181698] em28xx #0: i2c eeprom c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 
57
# [11196.181710] em28xx #0: i2c eeprom d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 
58
# [11196.181722] em28xx #0: i2c eeprom e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 
59
# [11196.181735] em28xx #0: i2c eeprom f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 
60
#
 
61
#############################################
 
62
# Where can I find my original eeprom?      #
 
63
#############################################
 
64
#
 
65
# e.g: Old dmesg output
 
66
#
 
67
########################################
 
68
# How this script works?               #
 
69
########################################
 
70
#
 
71
# To use it, you'll need to run the script, passing, as a parameter, the original dmesg with
 
72
# your original eeprom (before the corruption). Something like:
 
73
#
 
74
# shell> perl ./rewrite_eeprom my_old_dmesg_with_right_eeprom.txt > eeprom_script
 
75
#
 
76
# It will generate the eeprom_script file, with a script capable of recovering
 
77
# your eeprom.
 
78
#
 
79
# After having the proper eeprom_script generated, you'll need to run it, as root:
 
80
#
 
81
# shell> sh ./eeprom_script
 
82
#
 
83
#
 
84
# After running the script, your original contents should be restored. Try to
 
85
# remove it and reinsert to see if it will be properly detected again.
 
86
#
 
87
use Switch;
 
88
 
 
89
$argv = $ARGV[0];
 
90
 
 
91
# Files
 
92
$file_eeprom = "/tmp/eeprom-original.txt";
 
93
$file_bus = "/tmp/i2c-detect-bus.txt";
 
94
$file_addr = "/tmp/i2c-detect-addr.txt";
 
95
$file_i2c_tmp = "/tmp/i2ctmp.txt";
 
96
 
 
97
# Bus
 
98
$businfo = "";
 
99
$addrinfo = "";
 
100
 
 
101
# Modules
 
102
$modules = "em28xx|saa713";
 
103
$_  = $modules;
 
104
tr/|/ /d;
 
105
s/saa713/saa7134/g;
 
106
$modules_str = $_;
 
107
 
 
108
# eeprom stuff
 
109
$eeprom_backup_dir = "~/.eeprom";
 
110
$NR_EEPROM_REGS = 0;
 
111
 
 
112
##########################
 
113
# Subroutines            #
 
114
##########################
 
115
 
 
116
sub build_script
 
117
{
 
118
        my $script_prevent;
 
119
 
 
120
        # Building script
 
121
 
 
122
        $script_prevent  = "#!/bin/bash\n";
 
123
        $script_prevent .= "#\n";
 
124
        $script_prevent .= "# Notes:\n";
 
125
        $script_prevent .= "# - i2c_dev module should be loaded\n";
 
126
        $script_prevent .= "# - v4l driver should be loaded\n\n";
 
127
 
 
128
 
 
129
        $script_prevent .= "if [ ! \"\$UID\" = \"0\" ]; then\n\techo \"You must run this script as root\";\n\texit;\nfi\n\n";
 
130
 
 
131
        $script_prevent .= "i2cset &> /dev/null\n";
 
132
        $script_prevent .= "if [ ! \"\$\?\" = \"1\" ]; then\n";
 
133
        $script_prevent .= "\techo \"Please install i2c-tools package before continue.\";\n";
 
134
        $script_prevent .= "\texit;\n";
 
135
        $script_prevent .= "fi\n\n";
 
136
 
 
137
        $script_prevent .= "modprobe i2c-dev\n";
 
138
        $script_prevent .= "if [ ! \"\$\?\" = \"0\" ]; then\n";
 
139
        $script_prevent .= "\techo \"Can't load i2c-dev module.\";\n";
 
140
        $script_prevent .= "\texit;\n";
 
141
        $script_prevent .= "fi\n\n";
 
142
 
 
143
        $script_prevent .= "clear;\n";
 
144
        $script_prevent .= "echo \"";
 
145
        $script_prevent .=  "\n\033[1;31m#     #     #     ######   #     #  ###  #     #   #####\n";
 
146
        $script_prevent .= "#  #  #    # #    #     #  ##    #   #   ##    #  #     #\n";
 
147
        $script_prevent .= "#  #  #   #   #   #     #  # #   #   #   # #   #  #      \n";
 
148
        $script_prevent .= "#  #  #  #     #  ######   #  #  #   #   #  #  #  #  ####\n";
 
149
        $script_prevent .= "#  #  #  #######  #   #    #   # #   #   #   # #  #     #\n";
 
150
        $script_prevent .= "#  #  #  #     #  #    #   #    ##   #   #    ##  #     #\n";
 
151
        $script_prevent .= " ## ##   #     #  #     #  #     #  ###  #     #   #####\033[0m\n\n";
 
152
 
 
153
 
 
154
        $script_prevent .= "This tool is *ONLY RECOMMENDED* in cases of: LOST or CORRUPTED EEPROM data.\n";
 
155
        $script_prevent .= "Otherwise:\n\nYOU MAY *LOST* THE CURRENT EEPROM FROM YOUR DEVICE AND IT WILL MAKE YOUR BOARD ";
 
156
        $script_prevent .= "*DO NOT WORK* UNTIL YOU SET THE RIGHT EEPROM AGAIN!\n\n";
 
157
        $script_prevent .= "If you have *any doubt*, BEFORE run it contact people from: linux-media\@vger.kernel.org\n";
 
158
 
 
159
        $script_prevent .= "Are you \033[1;31mABSOLUTELY SURE\033[0m to continue? (yes or not)\";\n\n";
 
160
        $script_prevent .= "read confirmation;\n";
 
161
        $script_prevent .= "if \[ ! \"\$confirmation\" = \"yes\" \]; then\n";
 
162
        $script_prevent .= "\techo \"process aborted\";\n";
 
163
        $script_prevent .= "\texit;\n";
 
164
        $script_prevent .= "fi\n\n";
 
165
 
 
166
        $script_prevent .= "lsmod | egrep -e \"$modules\" &> /dev/null\n";
 
167
        $script_prevent .= "if [ ! \"\$\?\" = \"0\" ]; then\n";
 
168
        $script_prevent .= "\techo \"Aborting script.. None of the supported driver $modules_str are loaded. Did you forget to connect the device?\";\n";
 
169
        $script_prevent .= "\texit;";
 
170
        $script_prevent .= "\nfi\n\n";
 
171
 
 
172
        print $script_prevent;
 
173
}
 
174
 
 
175
sub check_user
 
176
{
 
177
        if ($>) {
 
178
                die "You must run this program as root\n";
 
179
        }
 
180
 
 
181
}
 
182
 
 
183
sub get_bus_and_addr
 
184
{
 
185
 
 
186
        my $lines = 0;
 
187
        my $output = "#!/bin/bash\n";
 
188
 
 
189
        system("\ni2cdetect -l | egrep -e \"$modules\" 2> /dev/null | cut -b 5 > $file_bus\n");
 
190
 
 
191
        # Checking number if lines
 
192
        open(FILE, $file_bus) or die "Can't open `$file_bus': $!";
 
193
        while (sysread FILE, $buffer, 1) {
 
194
                $lines += ($buffer =~ tr/\n//);
 
195
        }
 
196
        close FILE;
 
197
 
 
198
        switch ($lines) {
 
199
                case 0 {
 
200
                        $output .= "echo \"Could not detect i2c bus from any device, run again $0. Did you forget to connect the device?\";\n";
 
201
                        $output .= "echo \"Modules supported: $modules_str\";\n";
 
202
                        $output .= "exit;";
 
203
                        print $output;
 
204
                }
 
205
                case 1 {
 
206
                        # Starting script
 
207
                        &build_script;
 
208
                }
 
209
                else {
 
210
                        $output .= "humm, I got too many busses, please connect or plug just a hardware peer time!\n";
 
211
                        $output .= "Read a note inside the script!\n";
 
212
                        $output .= "exit;";
 
213
                        print $output;
 
214
                }
 
215
        }
 
216
 
 
217
        # Reading BUS from temporary file
 
218
        open (FILE, $file_bus);
 
219
        while (<FILE>) {
 
220
                $businfo = "$_";
 
221
                chomp($businfo);
 
222
        }
 
223
        close FILE;
 
224
 
 
225
        system("i2cdetect -y $businfo > $file_i2c_tmp 2> /dev/null");
 
226
        system("awk \'NR==7\' $file_i2c_tmp | cut -d \' \' -f 2 > $file_addr");
 
227
 
 
228
        # Reading BUS from temporary file
 
229
        open (FILE, $file_addr);
 
230
        while (<FILE>) {
 
231
                $addrinfo = "$_";
 
232
                chomp($addrinfo);
 
233
        }
 
234
 
 
235
        if($addrinfo eq "--") {
 
236
                print "\necho \"**** Failed to recognize bus address!\n**** Please connect your device *with eeprom* and try to run $0 tool again, aborted!\";\n";
 
237
                print "exit;";
 
238
        }
 
239
 
 
240
        # Double check
 
241
        $bkp_eeprom  = "\n\ni2cdetect -y $businfo > $file_i2c_tmp 2> /dev/null;\n";
 
242
        $bkp_eeprom .= "BUSCHECK=\`awk \'NR==7\' $file_i2c_tmp | cut -d \' \' -f 2\`;\n";
 
243
        $bkp_eeprom .= "rm -f $file_i2c_tmp;\n";
 
244
        $bkp_eeprom .= "if [ \"\$BUSCHECK\" == \"--\" ]; then\n";
 
245
        $bkp_eeprom .= "\t echo \"Aborting script.. I cannot make backup of your current eeprom.. It's not safe to continue!\";\n";
 
246
        $bkp_eeprom .= "\t exit;\n";
 
247
        $bkp_eeprom .= "fi\n\n";
 
248
 
 
249
        # Backup
 
250
        $bkp_eeprom .= "\nDATE=\`/bin/date +%Y%m%d_%I%M%S\`\n";
 
251
        $bkp_eeprom .= "echo \"\nMaking backup of current eeprom - dir [$eeprom_backup_dir/eeprom-\$DATE]\";\n";
 
252
        $bkp_eeprom .= "mkdir -p $eeprom_backup_dir\n";
 
253
        $bkp_eeprom .= "\necho \"\n--EEPROM DUMP START HERE--\n\" > $eeprom_backup_dir/eeprom-\$DATE\n";
 
254
        $bkp_eeprom .= "i2cdump -y $businfo 0x$addrinfo >> $eeprom_backup_dir/eeprom-\$DATE 2> /dev/null\n";
 
255
        $bkp_eeprom .= "if [ ! \"\$\?\" = \"0\" ]; then\n";
 
256
        $bkp_eeprom .= "\t echo \"Aborting script.. I cannot make backup of your current eeprom.. It's not safe to continue!\";\n";
 
257
        $bkp_eeprom .= "\t exit;";
 
258
        $bkp_eeprom .= "\nfi\n";
 
259
        $bkp_eeprom .= "\necho \"\n--DMESG START HERE--\n\" >> $eeprom_backup_dir/eeprom-\$DATE\n";
 
260
        $bkp_eeprom .= "\ndmesg >> $eeprom_backup_dir/eeprom-\$DATE\n";
 
261
 
 
262
        print $bkp_eeprom;
 
263
 
 
264
        close FILE;
 
265
}
 
266
 
 
267
sub print_i2c
 
268
{
 
269
        $cmd = "cat $argv | egrep \"eeprom [0-9a-f]\"| sed -e \"s/.*eeprom/eeprom/\" | cut -d ' ' -f 3-22 > $file_eeprom";
 
270
        system($cmd);
 
271
 
 
272
        open (INPUT, "$file_eeprom") or die "Can't open data file: $!";
 
273
 
 
274
        # Reading dump
 
275
        @eeprom = "";
 
276
        my $eeprom_pos = 0;
 
277
        while (!eof(INPUT)) {
 
278
                read(INPUT, $fc, 2);
 
279
                $eeprom[$eeprom_pos] = "0x$fc";
 
280
                seek(INPUT, tell(INPUT) + 1, 0);
 
281
                $eeprom_pos++;
 
282
                $NR_EEPROM_REGS++;
 
283
        }
 
284
        close INPUT;
 
285
 
 
286
        if ($NR_EEPROM_REGS == 0) {
 
287
                print "\necho \"**** Failed to recognize any dump in: $argv! Make sure that you have the right dump file before run again $0 tool, aborted!\";\n";
 
288
                print "exit;";
 
289
        }
 
290
 
 
291
        print "\n\necho \"\033[1;31m\n[DO NOT REMOVE YOUR DEVICE UNTIL THE UPDATE IS FINISHED]\033[0m\";\n";
 
292
        print "echo \"Press ENTER to start\";\n";
 
293
        print "read\n";
 
294
 
 
295
        for ($i=0; $i < $NR_EEPROM_REGS; $i++) {
 
296
                printf("i2cset -y $businfo 0x$addrinfo 0x%02x $eeprom[$i] b\n", $i);
 
297
        }
 
298
 
 
299
        printf("\necho \"\nDone! Remove and re-insert your device to see if it will be properly detected again. :-)\n\";\n");
 
300
}
 
301
 
 
302
################
 
303
# Main         #
 
304
################
 
305
 
 
306
&check_user;
 
307
 
 
308
if (@ARGV <= 0) {
 
309
 
 
310
        my $em28xx_note = "\n\033[1;31m\nNOTES\033[0m:\n\t Not tested against newer em28xx chipsets like the em2874 and em2884\n";
 
311
 
 
312
        print "\033[1;31m\nWARNING\033[0m:\n \t This script can *\033[1;31mDAMAGE\033[0m* your board, if you are not sure how to use it, *DO NOT* run it\n";
 
313
        print "\t Current modules supported: $modules_str *\033[1;31mONLY\033[0m*";
 
314
        print $em28xx_note;
 
315
        print "\t If you have *any doubt*, \033[1;31mBEFORE run it\033[0m contact people from: linux-media\@vger.kernel.org\n";
 
316
 
 
317
        print "\nUsage:\n";
 
318
        print "\tshell>perl $0 ./dmesg-dump-eeprom > eeprom_script.sh\n";
 
319
        print "\tshell>sh ./eeprom_script.sh\n\n";
 
320
        exit();
 
321
}
 
322
 
 
323
if (! -e $argv) {
 
324
        printf("No such file: $argv\n");
 
325
        exit();
 
326
}
 
327
 
 
328
# Calling sub routines
 
329
&get_bus_and_addr;
 
330
&print_i2c;
 
331
 
 
332
# Removing tmp files
 
333
system("rm -f $file_bus");
 
334
system("rm -f $file_addr");
 
335
system("rm -f $file_i2c_tmp");
 
336
system("rm -f $file_eeprom");