Eu encontrei uma solução no bugtracker do freedesktop.org envolvendo reescrever os dados do EDID sobre o barramento i2c.
Existe uma correção alternativa descrita no wiki do Arch , mas exigia acesso ao driver do Windows ou mais, criar uma linha de comando arcano do kernel para substituir a consulta EDID.
warning : esta é uma técnica bastante avançada. Você precisa entender os dumps hexadecimais, estar confortável com a noção de escrever para endereços de hardware e ser capaz de entender o que está acontecendo ao executar os vários comandos mostrados. Há alguns pontos em que as coisas não funcionam como deveriam - enquanto eu mostro as áreas de trabalho que usei eu não as explico, pois isso ocuparia muito espaço - você precisa ser capaz de entender o que está acontecendo para poder modificar a abordagem conforme necessário para sua situação.
warning : Isso envolve bisbilhotar em um nível de byte sobre o barramento i2c. Você pode irremediavelmente danificar o equipamento dessa maneira. Se o seu monitor já não estiver funcionando, você pode não ter muito a perder, mas se você errar o número do barramento i2c, pode acabar fazendo coisas no monitor externo.
Faça o download edid-tool , compile-o
wget https://bugs.freedesktop.org/attachment.cgi?id=91473
mv attachment.cgi\?id\=91473 edid-tool.c
gcc -std=gnu99 -O edid-tool.c
mv a.out edid-tool
instale alguns pacotes - em distribuições baseadas em debain você precisa:
sudo apt-get install i2c-tools libi2c-dev
Em seguida, instale o módulo do kernel:
sudo modprobe i2c-dev
Agora você deve ter /dev/i2c-1
, /dev/i2c-2
... correspondente ao barramento i2c 1, 2 etc
A próxima tarefa é descobrir em qual barramento i2c a tela afetada está ativada. Veja o relatório de bugs vinculado para mais detalhes - basicamente o que parece:
for i in 'ls /dev/i2c-*' ; do echo ; echo $i ; sudo ./edid-tool $i read ; done
/dev/i2c-1
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123 4567 89ab cdef
00000000 00 00 00 00 00 07 4f 00 06 10 bb 9c 00 00 00 00 |.... ..O. .... ....|
00000010 00 13 01 03 80 21 15 78 0a 50 c5 98 58 52 8e 27 |.... .!.x .P.. XR.'|
00000020 25 50 54 00 00 00 01 01 01 01 01 01 01 01 01 01 |%PT. .... .... ....|
00000030 01 01 01 01 01 01 7c 2e 90 a0 60 1a 1e 40 30 20 |.... ..|. ..'. .@0 |
00000040 36 00 4b cf 10 00 00 18 00 00 00 01 00 06 10 30 |6.K. .... .... ...0|
00000050 00 00 00 00 00 00 00 00 0a 20 00 00 00 fe 00 4c |.... .... . .. ...L|
00000060 50 31 35 34 57 45 33 2d 54 4c 42 31 00 00 00 fe |DELL 2001 TLB1 ....|
00000070 00 43 6f 6c 6f 72 20 4c 43 44 0a 20 20 20 00 dd |.Col or L CD. ..|
/dev/i2c-2
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123 4567 89ab cdef
00000000 ff ff ff ff ff ff ff ff 36 74 30 00 01 00 00 00 |.... .... 6t0. ....|
00000010 0a 16 01 03 80 73 41 78 0a cf 74 a3 57 4c b0 23 |.... .sAx ..t. WL.#|
00000020 09 48 4c 21 08 00 81 80 45 40 61 40 95 00 01 01 |.HL! .... E@a@ ....|
00000030 01 01 01 01 01 01 02 3a 80 18 71 38 2d 40 58 2c |.... ...: ..q8 -@X,|
00000040 45 00 c4 8e 21 00 00 1e 66 21 50 b0 51 00 1b 30 |E... !... f!P. Q..0|
00000050 00 70 26 44 c4 8e 21 00 00 1e 00 00 00 fc 00 4d |.p&D ..!. .... ...M|
00000060 53 74 61 72 20 44 65 6d 6f 0a 20 20 00 00 00 fd |Star Dem o. ....|
00000070 00 32 4b 1e 50 17 00 0a 20 20 20 20 20 20 01 fd |.2K. P... ..|
WARN at 209: Bad header: 0x0000 0000 0007 4f00
WARN at 217: Bad checksum: 0x5c
/dev/i2c-3
ERROR at 72: i2c_smbus_read_byte_data() failed: No such device or address
A tela com o problema provavelmente mostrará bad checksum
e bad header
erros. Além disso, pode haver detalhes do fabricante no texto - nesse caso, havia um monitor externo da Dell em i2c-1
e a tela interna quebrada do laptop estava em i2c-2
.
O restante da solução usará /dev/i2c-2
- não cegamente copie isso - veja acima como descobrir qual dispositivo você precisa usar.
Em seguida, imprima os dados EDID atuais:
~ $ sudo ./edid-tool /dev/i2c-2 read > edid-bad
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123 4567 89ab cdef
00000000 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |.... .... .... ....|
....
Agora use a ferramenta para corrigir os dados:
~ $ sudo ./edid-tool /dev/i2c-2 fix < edid-bad > edid-fixed
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123 4567 89ab cdef
00000000 00 ff ff ff ff ff ff 00 ff ff ff ff ff ff ff ff |.... .... .... ....|
....
Isso mostra que os dados EDID corrompidos têm ff
nos bytes 0x00
e 0x07
onde deveria ter 0x00
Valide os dados gerados usando parse-edid
para gerar uma seção Xorg.conf
:
$ parse-edid <edid-fixed
Checksum Correct
Section "Monitor"
Identifier "�
@"
ModelName "�
@"
VendorName "___"
# Monitor Manufactured week 0 of 2006
# EDID version 1.3
# Digital Display
DisplaySize 330 210
Gamma 2.20
Option "DPMS" "false"
Modeline "Mode 0" 68.94 1280 1296 1344 1408 800 801 804 816 -hsync -vsync
EndSection
Verifique se Modeline
corresponde às características de exibição da sua tela.
Agora, devemos poder carregar os dados fixos com
sudo ./edid-tool /dev/i2c-2 write < edid-fixed
mas não funcionou para o pôster no relatório de erros ou para mim.
No entanto, há uma maneira de corrigir valores individuais no barramento i2c:
~ $ sudo i2cdetect -y 2
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 51 52 53 54 55 56 57 -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
Isso mostra onde os dados edid estão localizados - nos bytes 0x50
a 0x57
.
Precisamos verificar os dados logo no início disso, então fazemos isso:
for i in 1 2 3 4 5 6 7 ; do echo -n "0x0$i " ; sudo i2cget -y 2 0x50 0x0"$i" b ; done
0x01 0x00
0x02 0xff
0x03 0xff
0x04 0xff
0x05 0xff
0x06 0xff
0x07 0xff
ok, então parece que edid-tool
corrigiu o primeiro byte, mas não conseguiu consertá-lo em 0x07
.
Então definimos isso por:
sudo i2cset -y 2 0x50 0x07 0x00 b
Então agora temos os dados corretos. Mas o monitor ainda não funciona. Execute novamente:
sudo ./edid-tool /dev/i2c-2 read > edid-bad
00000000 00 ff ff ff ff ff ff 00 ff ff ff ff ff ff ff ff |.... .... .... ....|
...
00000070 00 4c 54 4e 31 35 34 58 41 2d 4c 30 31 0a 00 a0 |.LTN 154X A-L0 1...|
Error : bad checksum
Compare essa saída com a saída de edid-tool ... fix
e vejo que o último byte difere.
Então corrijo isso com:
sudo i2cset -y 2 0x50 0x7f 0xc8 b
imediatamente o monitor volta à vida.