aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/cx231xx/parse_cx231xx.pl
blob: ad0ec7c432b95dfdbae7161dd1a191d1b39480ce (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#!/usr/bin/perl

#   Copyright (C) 2010 Mauro Carvalho Chehab <mchehab@redhat.com>
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation, version 2 of the License.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
# This small script parses register dumps generated by cx231xx driver
# with debug options enabled, generating a source code with the results
# of the dump.
#
# To use it, you may modprobe cx231xx with reg_debug=1, and do:
# dmesg | ./parse_em28xx.pl
#
# Also, there are other utilities that produce similar outputs, and it
# is not hard to parse some USB analyzers log into the expected format.
#

use strict;

sub parse_i2c($$$$$$)
{
	my $reqtype = shift;
	my $req = shift;
	my $wvalue = shift;
	my $windex = shift;
	my $wlen = shift;
	my $payload = shift;

	my $daddr = $wvalue >> 9;
	my $reserved = ($wvalue >>6 ) & 0x07;
	my $period = ($wvalue >> 4) & 0x03;
	my $addr_len = ($wvalue >> 2) & 0x03;
	my $nostop = ($wvalue >>1) & 0x01;
	my $sync = $wvalue & 0x01;

	if ($nostop) {
		$nostop="nostop ";
	} else {
		$nostop="";
	}
	if ($sync) {
		$sync="sync ";
	} else {
		$sync="";
	}
	my $type;
	my $i2c_channel;
	if ($reqtype > 128) {
		$type = "IN ";
		$i2c_channel = $req - 4;
	} else {
		$type = "OUT";
		$i2c_channel = $req;
	}
	if ($period == 0) {
		$period = "1Mbps";
	} elsif ($period == 1) {
		$period = "400kbps";
	} elsif ($period == 2) {
		$period = "100kbps";
	} else {
		$period = "???kbps";
	}
	printf("$type i2c channel#%d daddr 0x%02x %s addr_len %d %s%slen %d = ",
		$i2c_channel, $daddr, $period, $addr_len, $nostop, $sync,
		$wlen);
	if ($addr_len == 1) {
		printf("(saddr)%02x ", $windex & 0xff);
	} elsif ($addr_len == 2) {
		printf("(saddr)%04x ", $windex);
	}
	printf("$payload\n");
}

while (<>) {
	tr/A-F/a-f/;
	if (m/([4c]0) ([0-9a-f].) ([0-9a-f].) ([0-9a-f].) ([0-9a-f].) ([0-9a-f].) ([0-9a-f].) ([0-9a-f].)[\<\>\s]+(.*)/) {
		my $reqtype = hex($1);
		my $req = hex($2);
		my $wvalue = hex("$4$3");
		my $windex = hex("$6$5");
		my $wlen = hex("$8$7");
		my $payload = $9;

		if ($reqtype > 128 && (($req >= 4) && ($req <= 6))) {
			parse_i2c($reqtype, $req, $wvalue, $windex, $wlen, $payload);
		} elsif ($req < 3) {
			parse_i2c($reqtype, $req, $wvalue, $windex, $wlen, $payload);
		}
	}
}

Privacy Policy