EDIDエミュレータのEDIDを書き換えて遊ぶ

# EDID(E-EDID)
HDMIは複雑な仕様で、ソース機器(HDMI送信機)とシンク機器(HDMI受信機)間でデータをやり取りするためのいくつかのチャンネルを持っており、映像や音声などのデータを送信するためのTMDS、シンク機器の状態や構成情報などを送信するためのDDC、機器を高度に制御するためのCECなどがある。

EDID(EDIDの拡張版であるE-EDID)はDDCでやり取りされるデータで、シンク機器がどういうオーディオや映像フォーマットを扱えるかなどの情報を含んでおり、これをソース機器が受け取ることで適切に映像や音声を送信できるようになる。PCにモニタを接続しても画面が映らないという問題が起きることがあるが、この問題の原因の1つとして、ソース機器がシンク機器のEDIDを受信できなかったり、EDIDが破損しているといったことが挙げられる。

ちなみにソース機器やシンク機器というのが分かりづらいが、ソース機器はPCなど、シンク機器はモニタなどを想定するとわかりやすい。

# EDIDエミュレータ
ソース機器のHDMIアダプタに接続し、シンク機器が接続されていると誤認識させてソース機器にダミーのEDIDを送信できる、EDIDエミュレータやHDMIダミープラグなどと呼ばれる製品が存在する。

![EDIDエミュレータ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28644/727e9fff-77ae-39ce-ba2a-4ec0b8744de8.jpeg)

右はダミーのEDIDを送信するだけの一般的なものだが、左はパススルータイプのもので、EDIDエミュレータにさらにシンク機器を接続できる。パススルータイプの場合、ソース機器はEDIDエミュレータのダミーのEDIDを受信するだけでなく、EDIDエミュレータに接続されたシンク機器に映像や音声データを送信できることが大きな違いである。

# EDIDエミュレータの内部構造
EDIDエミュレータの内部構造を知るには基本的にEDIDエミュレータの物理的な破壊を伴うため、後で再利用しづらくなってしまう。EDIDエミュレータはコピー品が大量に販売されているようなので、似たような製品であれば内部構造も同様であると考えて良い。参考用に、既にEDIDエミュレータを分解している人がいたのでURLを貼っておく。

Emulating HDMI connection
https://blog.danman.eu/emulating-hdmi-connection/

HDMIの仮想ディスプレイアダプタを改造して自分好みの解像度の EDIDエミュレータを作成する方法
http://www.neko.ne.jp/~freewing//hardware/hdmi_edid_dummy_adapter_custom/

パススルータイプのものはこちら。

修改HDMI欺骗器EDID信息
https://blog.sharpbai.com/2022/10/%E4%BF%AE%E6%94%B9hdmi%E6%AC%BA%E9%AA%97%E5%99%A8edid%E4%BF%A1%E6%81%AF/

上記URLで述べられているように、EDIDエミュレータにはI2C接続方式のEEPROM(容量は256byte程度)が内蔵されており、このEEPROMにEDIDが書き込まれているようだ。ここで使用されているEEPROMの[24C02のデータシート](https://ww1.microchip.com/downloads/en/devicedoc/doc0180.pdf)によると、このEEPROMにはライトプロテクト機能が存在し、WP(Write Protect)ピンがGNDと接続されている場合は読み書き可、Vccと接続されている場合は書き込み不可となるようだ。

EDIDエミュレータのEEPROMはライトプロテクトされていないことも多いようで、この場合はEEPROMのデータを書き換えることでダミーのEDIDの内容を変更できる。手元にあるEDIDエミュレータでは、パススルータイプのものはライトプロテクトされていて書き込みできなかったが、パススルータイプでないものは書き込みできた。

# EDIDの読み書き

## ツール
EDIDを読み書きするためのツールがLinux環境向けに提供されているのでこれを利用する。

* [edid-rw](https://github.com/bulletmark/edid-rw)
    * EDIDの読み込みと書き込みができるツール
* [ddcutil](https://www.ddcutil.com/)
    * DDC/CI(Display Data Channel Command Interface)を使用して、I2C経由でMCCS(Monitor Control Command Set)を実装するモニタと通信するためのツール
* [i2c-tools](https://git.kernel.org/pub/scm/utils/i2c-tools/i2c-tools.git/about/)
    * I2CやSMBusを操作するためのツールやライブラリを提供する。ddcutilの依存パッケージ。
* [edid-decode](https://git.linuxtv.org/edid-decode.git/about/)
    * EDIDのデコーダ
 
## ツールのインストール
Arch Linuxの場合、edid-rw以外は非公式のものを含めてパッケージが存在するのでこれらをインストールする。edid-rwはGitHubリポジトリをクローンしておく。

```
$ yay -S i2c-tools ddcutil edid-decode-git
$ git clone https://github.com/bulletmark/edid-rw.git
```

なお、edid-rwがpythonモジュールのsmbusを要求するが、AURにあるpython-smbus-gitパッケージは古すぎてうまく動作しなかったため、代わりにpython-smbus2パッケージをインストールし、edid-rwのソースコードを書き換えてsmbus2で動作するようにした。

```
$ yay -S python-smbus2
$ sed -i -e "s/from smbus/from smbus2/" edid-rw/edid-rw
```

## I2Cモジュールのロード

DDCはI2Cバスを利用するため、I2Cバスを制御するためのカーネルモジュールをあらかじめロードしておく必要がある。

```
$ sudo modprobe i2c-dev
```

## モニタの検出
PCに接続されているモニタを検出する。

```
$ ddcutil detect
```

ノートPCに外部モニタを接続してコマンドを実行すると以下のような出力が得られた。Mfg idやModelからどのモニタの結果か判別できる。ノートPCの内蔵モニタも検出されているが、DDC/CIをサポートしていないようでInvalid displayとなっている。
後述のEDIDの取得では、この出力結果にあるI2C Busの番号(`/dev/i2c-8`の場合は`8`)が必要になるのでメモしておく。

```
Display 1
   I2C bus:  /dev/i2c-8
   DRM connector:           card2-HDMI-A-1
   EDID synopsis:
      Mfg id:               NEC - NEC Corporation
      Model:                LCD2490WUXi
      Product code:         26318  (0x66ce)
      Serial number:        87102068YJ
      Binary serial number: 16843009 (0x01010101)
      Manufacture year:     2008,  Week: 28
   VCP version:         2.0

Invalid display
   I2C bus:  /dev/i2c-9
   DRM connector:           card2-eDP-1
   EDID synopsis:
      Mfg id:               AUO - UNK
      Model:                
      Product code:         59020  (0xe68c)
      Serial number:        
      Binary serial number: 0 (0x00000000)
      Manufacture year:     2019,  Week: 0
   DDC communication failed
   This is an eDP laptop display. Laptop displays do not support DDC/CI.
```

EDIDエミュレータを接続した場合は以下のような出力が得られた。EDIDエミュレータは実際のモニタではないため、Invalid displayとなるようだ。

```
Invalid display   I2C bus:  /dev/i2c-8   DRM connector:           card2-HDMI-A-1
   EDID synopsis:
      Mfg id:               AOC - UNK
      Model:                28E850
      Product code:         3277  (0x0ccd)
      Serial number:        
      Binary serial number: 0 (0x00000000)
      Manufacture year:     2017,  Week: 3
   DDC communication failed
```

## EDIDの取得・デコード
edid-rwのクローン先フォルダで以下のコマンドを実行する。引数に対象のI2Cバスの番号が必要なので、`ddcutil detect`の出力結果を元に指定する。EDIDはバイナリデータのため、`edid-decode`でデコードして読めるようにする。

```
$ sudo ./edid-rw 8 | edid-decode
```

EDIDエミュレータから取得されたEDIDは以下の通り。最初にEDIDのバイナリデータが文字列で出力され、続いてEDIDのデコード結果が出力される。

このEDIDエミュレータはE-EDIDを持つようで、Block 0にBase EDID、Block 1にExtension Blockがあるようだ。EDIDから対応する解像度や周波数、オーディオなどの情報が分かる。もちろん、このEDIDはダミーであるため実際に画面を映したり音声を再生できるわけではない。

```
edid-decode (hex):

00 ff ff ff ff ff ff 00 05 e3 cd 0c 00 00 00 00
03 1b 01 03 80 3e 22 78 ea 1e c5 ae 4f 34 b1 26
0e 50 54 2f cf 00 d1 cf b3 00 a9 c0 95 00 81 81
81 00 81 c0 d1 00 02 3a 80 18 71 38 2d 40 58 2c
35 00 e0 0e 11 00 00 1a e2 68 00 a0 a0 40 2e 60
30 20 36 00 80 90 21 00 00 1a 56 5e 00 a0 a0 a0
29 50 30 20 36 00 80 68 21 00 00 1a 00 00 00 fc
00 32 38 45 38 35 30 0a 20 20 20 20 20 20 01 b2

02 03 3c 70 52 61 bf 05 04 60 65 66 03 01 1f 12
13 14 20 5d 5e 5f 62 23 09 07 07 83 01 00 00 6d
03 0c 00 10 00 38 44 20 00 60 01 02 03 67 d8 5d
c4 01 78 00 00 e3 05 03 01 e2 0f 71 88 83 40 a0
b0 08 2e 70 30 20 36 00 d0 c2 21 00 00 1a 04 74
00 30 f2 70 5a 80 30 20 46 00 c0 1c 32 00 00 1a
08 e8 00 30 f2 70 5a 80 b0 58 2a 00 c0 1c 32 00
00 1e 00 00 00 00 00 00 00 00 00 00 00 00 00 4e

----------------

Block 0, Base EDID:
  EDID Structure Version & Revision: 1.3
  Vendor & Product Identification:
    Manufacturer: AOC
    Model: 3277
    Made in: week 3 of 2017
  Basic Display Parameters & Features:
    Digital display
    Maximum image size: 62 cm x 34 cm
    Gamma: 2.20
    DPMS levels: Standby Suspend Off
    RGB color display
    First detailed timing is the preferred timing
  Color Characteristics:
    Red  : 0.6796, 0.3095
    Green: 0.2060, 0.6933
    Blue : 0.1513, 0.0546
    White: 0.3134, 0.3291
  Established Timings I & II:
    DMT 0x04:   640x480    59.940476 Hz   4:3     31.469 kHz     25.175000 MHz
    DMT 0x05:   640x480    72.808802 Hz   4:3     37.861 kHz     31.500000 MHz
    DMT 0x06:   640x480    75.000000 Hz   4:3     37.500 kHz     31.500000 MHz
    DMT 0x08:   800x600    56.250000 Hz   4:3     35.156 kHz     36.000000 MHz
    DMT 0x09:   800x600    60.316541 Hz   4:3     37.879 kHz     40.000000 MHz
    DMT 0x0a:   800x600    72.187572 Hz   4:3     48.077 kHz     50.000000 MHz
    DMT 0x0b:   800x600    75.000000 Hz   4:3     46.875 kHz     49.500000 MHz
    DMT 0x10:  1024x768    60.003840 Hz   4:3     48.363 kHz     65.000000 MHz
    DMT 0x11:  1024x768    70.069359 Hz   4:3     56.476 kHz     75.000000 MHz
    DMT 0x12:  1024x768    75.028582 Hz   4:3     60.023 kHz     78.750000 MHz
    DMT 0x24:  1280x1024   75.024675 Hz   5:4     79.976 kHz    135.000000 MHz
  Standard Timings:
    GTF     :  1920x1080   75.000068 Hz  16:9     84.600 kHz    220.637000 MHz
    DMT 0x3a:  1680x1050   59.954250 Hz  16:10    65.290 kHz    146.250000 MHz
    DMT 0x53:  1600x900    60.000000 Hz  16:9     60.000 kHz    108.000000 MHz (RB)
    DMT 0x2f:  1440x900    59.887445 Hz  16:10    55.935 kHz    106.500000 MHz
    GTF     :  1280x1024   60.999806 Hz   5:4     64.721 kHz    110.802000 MHz
    DMT 0x1c:  1280x800    59.810326 Hz  16:10    49.702 kHz     83.500000 MHz
    DMT 0x55:  1280x720    60.000000 Hz  16:9     45.000 kHz     74.250000 MHz
    DMT 0x45:  1920x1200   59.884600 Hz  16:10    74.556 kHz    193.250000 MHz
  Detailed Timing Descriptors:
    DTD 1:  1920x1080   60.000000 Hz  16:9     67.500 kHz    148.500000 MHz (480 mm x 270 mm)
                 Hfront   88 Hsync  44 Hback  148 Hpol P
                 Vfront    3 Vsync   5 Vback   37 Vpol N
    DTD 2:  2560x1600   59.971589 Hz  16:10    98.713 kHz    268.500000 MHz (640 mm x 400 mm)
                 Hfront   48 Hsync  32 Hback   80 Hpol P
                 Vfront    3 Vsync   6 Vback   37 Vpol N
    DTD 3:  2560x1440   59.950550 Hz  16:9     88.787 kHz    241.500000 MHz (640 mm x 360 mm)
                 Hfront   48 Hsync  32 Hback   80 Hpol P
                 Vfront    3 Vsync   6 Vback   32 Vpol N
    Display Product Name: '28E850'
  Extension blocks: 1
Checksum: 0xb2

----------------

Block 1, CTA-861 Extension Block:
  Revision: 3
  Basic audio support
  Supports YCbCr 4:4:4
  Supports YCbCr 4:2:2
  Native detailed modes: 0
  Video Data Block:
    VIC  97:  3840x2160   60.000000 Hz  16:9    135.000 kHz    594.000000 MHz
    VIC  63:  1920x1080  120.000000 Hz  16:9    135.000 kHz    297.000000 MHz (native)
    VIC   5:  1920x1080i  60.000000 Hz  16:9     33.750 kHz     74.250000 MHz
    VIC   4:  1280x720    60.000000 Hz  16:9     45.000 kHz     74.250000 MHz
    VIC  96:  3840x2160   50.000000 Hz  16:9    112.500 kHz    594.000000 MHz
    VIC 101:  4096x2160   50.000000 Hz 256:135  112.500 kHz    594.000000 MHz
    VIC 102:  4096x2160   60.000000 Hz 256:135  135.000 kHz    594.000000 MHz
    VIC   3:   720x480    59.940060 Hz  16:9     31.469 kHz     27.000000 MHz
    VIC   1:   640x480    59.940476 Hz   4:3     31.469 kHz     25.175000 MHz
    VIC  31:  1920x1080   50.000000 Hz  16:9     56.250 kHz    148.500000 MHz
    VIC  18:   720x576    50.000000 Hz  16:9     31.250 kHz     27.000000 MHz
    VIC  19:  1280x720    50.000000 Hz  16:9     37.500 kHz     74.250000 MHz
    VIC  20:  1920x1080i  50.000000 Hz  16:9     28.125 kHz     74.250000 MHz
    VIC  32:  1920x1080   24.000000 Hz  16:9     27.000 kHz     74.250000 MHz
    VIC  93:  3840x2160   24.000000 Hz  16:9     54.000 kHz    297.000000 MHz
    VIC  94:  3840x2160   25.000000 Hz  16:9     56.250 kHz    297.000000 MHz
    VIC  95:  3840x2160   30.000000 Hz  16:9     67.500 kHz    297.000000 MHz
    VIC  98:  4096x2160   24.000000 Hz 256:135   54.000 kHz    297.000000 MHz
  Audio Data Block:
    Linear PCM:
      Max channels: 2
      Supported sample rates (kHz): 48 44.1 32
      Supported sample sizes (bits): 24 20 16
  Speaker Allocation Data Block:
    FL/FR - Front Left/Right
  Vendor-Specific Data Block (HDMI), OUI 00-0C-03:
    Source physical address: 1.0.0.0
    DC_36bit
    DC_30bit
    DC_Y444
    Maximum TMDS clock: 340 MHz
    Extended HDMI video details:
      HDMI VICs:
        HDMI VIC 1:  3840x2160   30.000000 Hz  16:9     67.500 kHz    297.000000 MHz
        HDMI VIC 2:  3840x2160   25.000000 Hz  16:9     56.250 kHz    297.000000 MHz
        HDMI VIC 3:  3840x2160   24.000000 Hz  16:9     54.000 kHz    297.000000 MHz
  Vendor-Specific Data Block (HDMI Forum), OUI C4-5D-D8:
    Version: 1
    Maximum TMDS Character Rate: 600 MHz
  Colorimetry Data Block:
    xvYCC601
    xvYCC709
    Gamut Boundary Description Metadata Profile P0
  YCbCr 4:2:0 Capability Map Data Block:
    VIC  97:  3840x2160   60.000000 Hz  16:9    135.000 kHz    594.000000 MHz
    VIC  96:  3840x2160   50.000000 Hz  16:9    112.500 kHz    594.000000 MHz
    VIC 101:  4096x2160   50.000000 Hz 256:135  112.500 kHz    594.000000 MHz
    VIC 102:  4096x2160   60.000000 Hz 256:135  135.000 kHz    594.000000 MHz
  Detailed Timing Descriptors:
    DTD 4:  2880x1800   60.001711 Hz  16:10   110.763 kHz    336.720000 MHz (720 mm x 450 mm)
                 Hfront   48 Hsync  32 Hback   80 Hpol P
                 Vfront    3 Vsync   6 Vback   37 Vpol N
    DTD 5:  3840x2160   30.000000 Hz  16:9     67.500 kHz    297.000000 MHz (960 mm x 540 mm)
                 Hfront   48 Hsync  32 Hback  480 Hpol P
                 Vfront    4 Vsync   6 Vback   80 Vpol N
    DTD 6:  3840x2160   60.000000 Hz  16:9    135.000 kHz    594.000000 MHz (960 mm x 540 mm)
                 Hfront  176 Hsync  88 Hback  296 Hpol P
                 Vfront    2 Vsync  10 Vback   78 Vpol P
Checksum: 0x4e  Unused space in Extension Block: 13 bytes
```

## EDIDのファイル出力
EDIDはファイルに保存することもできる。

```
$ sudo ./edid-rw 8 > edid.bin
```

## EDIDの書き込み(書き換え可能な場合のみ)
シンク機器のEDIDが書き換え可能な場合、保存しておいたEDIDの内容に書き換えることができる。ちなみに書き込みに失敗してもこのコマンドがエラーにならないことがあるようで、正しく書き込みできたかどうかはEDIDを読み直して確認する必要がある。手元にあるものでは、HDMI音声分離器のようにHDMI関連の機能を1チップで実装しているような製品は、EDIDの書き込みができなくてもエラーにならなかった。

```
$ sudo ./edid-rw -w 8 < edid.bin
```

## EDIDの強制
少し脱線するが、Linuxの場合、EDIDエミュレータを使用しなくてもシンク機器から取得したEDIDを無視して一時的に指定したEDIDを使用するように強制することができる。この変更は新しく接続されたモニタにのみ有効であるため、変更後はHDMIケーブルを差し直す必要がある。

`2/HDMI-A-1`の部分は環境によって異なるため、`/sys/kernel/debug/dri`のサブフォルダ以下を見て、対象の接続先(`HDMI-A-1`など)が含まれているパスを指定する。

```
$ sudo bash -c "cat edid.bin > /sys/kernel/debug/dri/2/HDMI-A-1/edid_override"
```

強制したEDIDを無効化するには、以下のコマンドを実行後HDMIケーブルを差し直す。

```
$ sudo bash -c "echo -n reset > /sys/kernel/debug/dri/2/HDMI-A-1/edid_override"
```

# EDIDエミュレータのライトプロテクトの解除
手元にあるパススルータイプのEDIDエミュレータは、ライトプロテクトが有効になっていてそのままでは書き込みできなかった。このライトプロテクトをEDIDエミュレータを破壊することなく無効化する手段を考える。

[修改HDMI欺骗器EDID信息](https://blog.sharpbai.com/2022/10/%E4%BF%AE%E6%94%B9hdmi%E6%AC%BA%E9%AA%97%E5%99%A8edid%E4%BF%A1%E6%81%AF/)によると、EEPROMのWPピンはHDMIのHPDピンに接続されており、1kΩの抵抗で5vにプルアップされているようだ。従って、HPDピンをGNDに接続すれば書き込み可能になる。ちなみにHPD(Hot Plug Detect)は、ソース機器にシンク機器が接続されたことを検知するために使用されるものである。

上記URLではCH341AというROMライタを使用してEEPROMを書き換える手法を採用しているが、こういったROMライタがなくてもLinuxが動作するRaspberry PiのGPIOを利用することで代用できる。後は、EDIDエミュレータのHDMIアダプタのオス側の各ピンとつながる線を引き出して、GPIOに配線すればよい。

HDMIアダプタから線を引き出すには、[HDMIテストボード](https://ja.aliexpress.com/item/1005004343592426.html)という、HDMIコネクタ(メス)の各ピンを2.54mmピッチに引き出したHDMIコネクタ実装済みのPCBが販売されているので、こういったものを利用すると便利である。写真のものはHDMIコネクタのオス・メス両方に対応したもので、両側のコネクタは各ピンが直結されているため延長アダプタとしても一応使用できる。
![HDMIテストボード](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28644/44505b26-922f-d8a5-9eeb-ff12564c8173.jpeg)

別の方法としては、HDMI延長アダプタとケーブルが太めのHDMIケーブルを用意し、HDMIケーブルを切断して必要な線を引っ張り出す、といった方法もある。ただし、ケーブルが非常に細く手間がかかるためお勧めはしない。

## Raspberry Piの事前準備
Raspberry Pi OSに必要なパッケージをインストールし、edid-rwをGitHubリポジトリからクローンしておく。

```
$ sudo apt update
$ sudo apt install i2c-tools edid-decode python3-smbus
$ git clone https://github.com/bulletmark/edid-rw.git
```

また、I2Cを制御できるようにRaspberry Pi OSの設定を変更する。以下のコマンドを実行し、メニューからInterface Options->I2CをYesに変更することでGPIOのI2Cを制御できるようになる。なお、HDMIアダプタと繋がっているI2Cバスはこの設定だけでは制御できないため、Raspberry PiのHDMIアダプタに接続したシンク機器のEDIDを取得したい等の場合には https://www.ddcutil.com/raspberry/ に従ってRaspberry Pi OSの設定を変更する必要がある。

```
$ sudo raspi-config
```

`i2cdetect`コマンドを実行してI2Cバスの一覧が表示されれば問題ない。

```
$ i2cdetect -l
```

Raspberry Pi 3Bでは、GPIOのSDA、SCLに接続した機器をI2Cバスの`i2c-1`で制御できる。ちなみにHDMIと繋がっているI2Cバスも制御できるように設定してある場合、HDMIと繋がっているI2Cバスは`i2c-2`になるようだ。

```
i2c-1	i2c       	bcm2835 (i2c@7e804000)          	I2C adapter
```

## 配線
まず初めにRaspberry Piの[ピンアサイン](https://pinout.xyz/#)を確認する。必要なピンは、電源供給のための5vピン(EEPROMが3.3vでも動作する場合は3.3vでも可)、Ground(GND)、I2CのためのSDAとSCLの4本のみで、対応するピンの番号と機能は以下の通り。5vやGroundは他にも同じ機能を持つピンがあるので、それを使用しても良い。

| Pin | 機能 |
| :--: | --- |
| 2 | 5v |
| 3 | SDA |
| 5 | SCL |
| 6 | Ground |

次にHDMIの[ピンアサイン](https://ja.wikipedia.org/wiki/HDMI)を確認する。必要なピンはRaspberry Pi側と基本的には同じだが、EEPROMのライトプロテクトを解除するためにはHPDピンも必要になる。対応するピンの番号と機能は以下の通り。

| Pin | 機能 |
| :--: | --- |
| 15 | SCL |
| 16 | SDA |
| 17 | Ground |
| 18 | 5v |
| 19 | HPD |

後はRaspberry PiとHDMIの各ピンを同じ機能のもの同士を繋ぐように配線すれば良い。なお、HPDはGroundと繋ぐことでEEPROMのライトプロテクトを解除できる。配線が間違っている場合、Raspberry Piが壊れたりケーブルが溶けたりすることもあるので十分注意する必要がある。今回は適当に見つけた記事の内容を信用して配線したが、配線が正しくても内部回路が異なる場合は故障の原因になるため、本当なら自分でEDIDエミュレータを分解して確認したほうが良い。

![配線例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28644/d823c756-329e-4ed0-6618-942bee78bd12.jpeg)

写真ではブレッドボードを経由して配線しているが、直結しても良い。配線は赤が5v、黒がGround、青がSDA、白がSCL、黄がHPDである。斜めに配線してある赤いジャンパーワイヤはブレッドボードの両側にある5vライン同士、Groundライン同士を接続するためのもの。EDIDエミュレータはHDMIアダプタのオス側をHDMIテストボードのメス側と接続する。

## EDIDの書き換え
配線が正しければ前述の通りedid-rwを使用してEDIDを書き込みできる。なお、HPDをGroundと接続しない場合、EEPROMがライトプロテクトされた状態になるので書き込みに失敗する。

```
$ sudo ./edid-rw -w 1 < edid.bin
```

# おまけ1
HDMIテストボードを使用せず、HDMIケーブルを加工して配線したものもあるので参考までに載せておく。

## 部品・工具など
作業に必要と思われるものを列挙しておく。

* HDMI延長アダプタ
    * ダイソーで入手できる。
* HDMIケーブル
    * ケーブルは太いほうが加工しやすい。ダイソーで入手できる。
* テスター
    * 導通確認用。HDMIの各ピンとHDMIケーブルの各線との対応関係を調べるために使用する。
* カッター
    * HDMIケーブルの切断および線の被膜を剥くために使用する。
* 0.2mm程度の針金などの導体
    * 導通確認用。HDMIコネクタオス側の小さな穴に刺しておき、テスター棒の先を当てて使用すると各ピンの導通確認がしやすい。
* ピンヘッダ
    * HDMIケーブルの必要な線の先にはんだ付けしておくと便利。
* はんだごて
    * ピンヘッダのはんだ付けに使用。
* はんだ
    * ピンヘッダのはんだ付けに使用。

## HDMIケーブルとピン番号の対応関係の調査
ダイソーのHDMIケーブルを切断し、テスターでHDMIコネクタの各ピンと対応するケーブルの被膜色を調査した。

![調査結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28644/2446a444-649a-f9ab-927a-87a4aa304b1b.png)

ダイソーのHDMIケーブルは、3本の線を束ねてさらにシールドされているものと、そうでないものがある。シールドされているものはTMDS Dataのような必要のないピンは深追いせず、束ねられている3本のうちどれかが導通すれば対応関係ありとした。GroundとHPD(とUtility)は必要な線だが、シールドされていたためさらに被膜を剥いてばらす必要があった。

## 加工例
必要な5v、Ground、SDA、SCL、HPDの各線の被膜を剥いた状態。

![被膜を剥いた状態](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28644/0a3778e0-2840-e056-831a-087ae82c8673.jpeg)

各線にピンヘッダをはんだ付けした状態。イモはんだぽくなっているが気にしてはいけない。浮いた状態ではんだ付けしたのでやりづらいのと線が細すぎるのが悪い。

![完成形](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28644/5e5ae63c-1d70-60ae-0f38-fe1cb35c1946.jpeg)

## 配線例
HDMIケーブルの加工が終われば、後はHDMIテストボードを使用する場合と同じように配線すれば良い。

![HDMIケーブルを加工した場合の配線例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28644/fab5d72f-8528-2309-1fe9-0a2d9496791e.jpeg)

写真はHPDをGroundと繋ぐ前の状態である。加工したHDMIケーブルとEDIDエミュレータをHDMI延長アダプタで接続して使用する。ここではRaspberry Pi側から5vではなく3.3vのピンから電源を取っているが、問題なくEDIDの書き込みができた。

# おまけ2

DDC/CIという規格では、モニタ側で設定できる色温度や入力切替、モニタのON/OFFなどをHDMI/DVI/VGAのDDC用のピン経由で操作できるものがあり、この機能に対応しているモニタはddcutil等を使ってPCから操作できるようになっている。[DDC/CIの詳細はこちら](https://takabus.com/tips/wp-content/uploads/2021/11/DDCCI_documentation_mccsV3.pdf)。


## DDC/CIの機能一覧の取得
ディスプレイ番号1の機能一覧を表示するには以下のコマンドを実行する。ディスプレイ番号は、`ddcutil detect`の出力結果にある`Display 1`などの番号である。

```
$ ddcutil capabilities -d 1
```

対応している機能の一覧が出力される。

```
Model: LCD2490WUXiMCCS version: 2.0
Commands:
   Op Code: 01 (VCP Request)
   Op Code: 02 (VCP Response)
   Op Code: 03 (VCP Set)
   Op Code: 07 (Timing Request)
   Op Code: 0C (Save Settings)
   Op Code: C2 (Unrecognized operation code)
   Op Code: C4 (Unrecognized operation code)
   Op Code: C6 (Unrecognized operation code)
   Op Code: C8 (Unrecognized operation code)
   Op Code: F3 (Capabilities Request)
VCP Features:
   Feature: 02 (New control value)
   Feature: 04 (Restore factory defaults)
   Feature: 05 (Restore factory brightness/contrast defaults)
   Feature: 06 (Restore factory geometry defaults)
   Feature: 08 (Restore color defaults)
   Feature: 0B (Color temperature increment)
   Feature: 0C (Color temperature request)
   Feature: 10 (Brightness)
   Feature: 12 (Contrast)
   Feature: 14 (Select color preset)
      Values:
         01: sRGB
         02: Display Native
         04: 5000 K
         06: 7500 K
         07: 8200 K
         08: 9300 K
         0b: User 1
   Feature: 16 (Video gain: Red)
   Feature: 18 (Video gain: Green)
   Feature: 1A (Video gain: Blue)
   Feature: 20 (Horizontal Position)
   Feature: 30 (Vertical Position)
   Feature: 68 (Unrecognized feature)
      Values: 01 02 03 04 05 06 07 09 (interpretation unavailable)
   Feature: 6C (Video black level: Red)
   Feature: 6E (Video black level: Green)
   Feature: 70 (Video black level: Blue)
   Feature: 87 (Sharpness)
   Feature: 8C (TV Sharpness)
   Feature: 9B (6 axis hue control: Red)
   Feature: 9C (6 axis hue control: Yellow)
   Feature: 9D (6 axis hue control: Green)
   Feature: 9E (6 axis hue control: Cyan)
   Feature: 9F (6 axis hue control: Blue)
   Feature: A0 (6 axis hue control: Magenta)
   Feature: AA (Screen Orientation)
   Feature: B0 (Settings)
   Feature: B6 (Display technology type)
   Feature: DF (VCP Version)
   Feature: E3 (Manufacturer specific feature)
   Feature: F4 (Manufacturer specific feature)
   Feature: F5 (Manufacturer specific feature)
      Values: 01 02 03 04 05 06 07 09 (interpretation unavailable)
   Feature: F6 (Manufacturer specific feature)
   Feature: FA (Manufacturer specific feature)
   Feature: FB (Manufacturer specific feature)
   Feature: FC (Manufacturer specific feature)
   Feature: FE (Manufacturer specific feature)
   Feature: FF (Manufacturer specific feature)
```

## 各機能の設定値の取得
例としてディスプレイ番号1のFeature 14(Select color preset)の設定値を取得する場合、以下のコマンドを実行する。

```
$ ddcutil getvcp 14 -d 1
```

設定値は`0x02`となっており、Display Nativeに設定されていることが分かる。

```
VCP code 0x14 (Select color preset           ): Display Native (sl=0x02)
```

## 各機能の設定値の変更
対応している場合は設定値を変更することもできる。例としてディスプレイ番号1のFeature 14(Select color preset)の設定値を`0x01`に変更する場合、以下のコマンドを実行する。

```
$ ddcutil setvcp 14 01 -d 1
```

設定値を取得すると変更されていることが確認できる。

```
$ ddcutil getvcp 14 -d 1
VCP code 0x14 (Select color preset           ): sRGB (sl=0x01)
```