This file is indexed.

/usr/bin/decode-edid is in i2c-tools 3.1.1-1.

This file is owned by root:root, with mode 0o755.

The actual contents of the file can be viewed below.

  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
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#!/usr/bin/perl -w
#
# Copyright (C) 2003-2008 Jean Delvare <jdelvare@suse.de>
#
#    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; either version 2 of the License, or
#    (at your option) any later version.
#
#    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.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#    MA 02110-1301 USA.
#
# EEPROM data decoding for EDID. EDID (Extended Display Identification
# Data) is a VESA standard which allows storing (on manufacturer's side)
# and retrieving (on user's side) of configuration information about
# displays, such as manufacturer, serial number, physical dimensions and
# allowed horizontal and vertical refresh rates.
#
# Using the eeprom kernel driver, you have two possibilities to
# make use of these data:
#  1* The ddcmon script.
#  2* This script.
# Both solutions will return a different kind of information. The first
# method will report user-interesting information, such as the model number
# or the year of manufacturing. The second method will report video-card-
# interesting information, such as video modes and refresh rates.
#
# Note that this script does almost nothing by itself. It simply converts
# what it finds in /proc to binary data to feed the parse-edid program.
# The parse-edid program was written by John Fremlin and is available at
# the following address:
#   http://john.fremlin.de/programs/linux/read-edid/

use strict;
use Fcntl qw(:DEFAULT :seek);
use vars qw($bus $address);
use constant PROCFS => 1;
use constant SYSFS  => 2;

# parse-edid will typically be installed in /usr/sbin or /usr/local/sbin
# even though regular users can run it
$ENV{PATH} .= ':/usr/local/sbin'
	if $ENV{PATH} !~ m,(^|:)/usr/local/sbin/?(:|$),
	&& -x '/usr/local/sbin/parse-edid';
$ENV{PATH} .= ':/usr/sbin'
	if $ENV{PATH} !~ m,(^|:)/usr/sbin/?(:|$),
	&& -x '/usr/sbin/parse-edid';

sub edid_valid_procfs
{
	my ($bus, $addr) = @_;

	open EEDATA, "/proc/sys/dev/sensors/eeprom-i2c-$bus-$addr/00";
	my $line = <EEDATA>;
	close EEDATA;
	return 1
		if $line =~ m/^0 255 255 255 255 255 255 0 /;
	return 0;
}

# Only used for sysfs
sub rawread
{
	my ($filename, $length, $offset) = @_;
	my $bytes = '';

	sysopen(FH, $filename, O_RDONLY)
		or die "Can't open $filename";
	if ($offset)
	{
		sysseek(FH, $offset, SEEK_SET)
			or die "Can't seek in $filename";
	}

	$offset = 0;
	while ($length)
	{
		my $r = sysread(FH, $bytes, $length, $offset);
		die "Can't read $filename"
			unless defined($r);
		die "Unexpected EOF in $filename"
			unless $r;
		$offset += $r;
		$length -= $r;
	}
	close(FH);

	return $bytes;
}

sub edid_valid_sysfs
{
	my ($bus, $addr) = @_;
	my $bytes = rawread("/sys/bus/i2c/devices/$bus-00$addr/eeprom", 8, 0);

	return 1
		if $bytes eq "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00";
	return 0;
}

sub bus_detect
{
	my $max = shift;

	for (my $i=0; $i<$max; $i++)
	{
		if (-r "/proc/sys/dev/sensors/eeprom-i2c-$i-50/00")
		{
			if (edid_valid_procfs($i, '50'))
			{
				print STDERR
					"decode-edid: using bus $i (autodetected)\n";
				return $i;
			}
		}
		elsif (-r "/sys/bus/i2c/devices/$i-0050/eeprom")
		{
			if (edid_valid_sysfs($i, '50'))
			{
				print STDERR
					"decode-edid: using bus $i (autodetected)\n";
				return $i;
			}
		}
	}

	return; # default
}

sub edid_decode
{
	my ($bus, $addr, $mode) = @_;

	# Make sure it is an EDID EEPROM.

	unless (($mode == PROCFS && edid_valid_procfs ($bus, $addr))
	     || ($mode == SYSFS  && edid_valid_sysfs  ($bus, $addr)))
	{
		print STDERR
			"decode-edid: not an EDID EEPROM at $bus-$addr\n";
		return;
	}

	$SIG{__WARN__} = sub { };
	open PIPE, "| parse-edid"
		or die "Can't open parse-edid. Please install read-edid.\n";
	delete $SIG{__WARN__};
	binmode PIPE;

	if ($mode == PROCFS)
	{
		for (my $i=0; $i<=0x70; $i+=0x10)
		{
			my $file = sprintf '%02x', $i;
			my $output = '';
			open EEDATA, "/proc/sys/dev/sensors/eeprom-i2c-$bus-$addr/$file"
				or die "Can't read /proc/sys/dev/sensors/eeprom-i2c-$bus-$addr/$file";
			while(<EEDATA>)
			{
				foreach my $item (split)
				{
					$output .= pack "C", $item;
				}
			}
			close EEDATA;
			print PIPE $output;
		}
	}
	elsif ($mode == SYSFS)
	{
		print PIPE rawread("/sys/bus/i2c/devices/$bus-00$address/eeprom", 128, 0);
	}

	close PIPE;
}

# Get the address. Default to 0x50 if not given.
$address = $ARGV[1] || 0x50;
# Convert to decimal, whatever the value.
$address = oct $address if $address =~ m/^0/;
# Convert to an hexadecimal string.
$address = sprintf '%02x', $address;

# Get the bus. Try to autodetect if not given.
$bus = $ARGV[0] if defined $ARGV[0];
$bus = bus_detect(8) unless defined $bus;

if(defined $bus)
{
	print STDERR
		"decode-edid: decode-edid version 1.1\n";
	if (-r "/proc/sys/dev/sensors/eeprom-i2c-$bus-$address")
	{
		edid_decode ($bus, $address, PROCFS);
		exit 0;
	}
	elsif (-r "/sys/bus/i2c/devices/$bus-00$address")
	{
		edid_decode ($bus, $address, SYSFS);
		exit 0;
	}
}

print STDERR
	"EDID EEPROM not found.  Please make sure that the eeprom module is loaded.\n";
print STDERR
	"Maybe your EDID EEPROM is on another bus.  Try \"decode-edid ".($bus+1)."\".\n"
	if defined $bus;