|
| 1 | +.. SPDX-License-Identifier: GPL-2.0 |
| 2 | +
|
| 3 | +======== |
| 4 | +HDMI CEC |
| 5 | +======== |
| 6 | + |
| 7 | +Supported hardware in mainline |
| 8 | +============================== |
| 9 | + |
| 10 | +HDMI Transmitters: |
| 11 | + |
| 12 | +- Exynos4 |
| 13 | +- Exynos5 |
| 14 | +- STIH4xx HDMI CEC |
| 15 | +- V4L2 adv7511 (same HW, but a different driver from the drm adv7511) |
| 16 | +- stm32 |
| 17 | +- Allwinner A10 (sun4i) |
| 18 | +- Raspberry Pi |
| 19 | +- dw-hdmi (Synopsis IP) |
| 20 | +- amlogic (meson ao-cec and ao-cec-g12a) |
| 21 | +- drm adv7511/adv7533 |
| 22 | +- omap4 |
| 23 | +- tegra |
| 24 | +- rk3288, rk3399 |
| 25 | +- tda998x |
| 26 | +- DisplayPort CEC-Tunneling-over-AUX on i915, nouveau and amdgpu |
| 27 | +- ChromeOS EC CEC |
| 28 | +- CEC for SECO boards (UDOO x86). |
| 29 | +- Chrontel CH7322 |
| 30 | + |
| 31 | + |
| 32 | +HDMI Receivers: |
| 33 | + |
| 34 | +- adv7604/11/12 |
| 35 | +- adv7842 |
| 36 | +- tc358743 |
| 37 | + |
| 38 | +USB Dongles (see below for additional information on how to use these |
| 39 | +dongles): |
| 40 | + |
| 41 | +- Pulse-Eight: the pulse8-cec driver implements the following module option: |
| 42 | + ``persistent_config``: by default this is off, but when set to 1 the driver |
| 43 | + will store the current settings to the device's internal eeprom and restore |
| 44 | + it the next time the device is connected to the USB port. |
| 45 | +- RainShadow Tech. Note: this driver does not support the persistent_config |
| 46 | + module option of the Pulse-Eight driver. The hardware supports it, but I |
| 47 | + have no plans to add this feature. But I accept patches :-) |
| 48 | + |
| 49 | +Miscellaneous: |
| 50 | + |
| 51 | +- vivid: emulates a CEC receiver and CEC transmitter. |
| 52 | + Can be used to test CEC applications without actual CEC hardware. |
| 53 | + |
| 54 | +- cec-gpio. If the CEC pin is hooked up to a GPIO pin then |
| 55 | + you can control the CEC line through this driver. This supports error |
| 56 | + injection as well. |
| 57 | + |
| 58 | + |
| 59 | +Utilities |
| 60 | +========= |
| 61 | + |
| 62 | +Utilities are available here: https://git.linuxtv.org/v4l-utils.git |
| 63 | + |
| 64 | +``utils/cec-ctl``: control a CEC device |
| 65 | + |
| 66 | +``utils/cec-compliance``: test compliance of a remote CEC device |
| 67 | + |
| 68 | +``utils/cec-follower``: emulate a CEC follower device |
| 69 | + |
| 70 | +Note that ``cec-ctl`` has support for the CEC Hospitality Profile as is |
| 71 | +used in some hotel displays. See http://www.htng.org. |
| 72 | + |
| 73 | +Note that the libcec library (https://github.com/Pulse-Eight/libcec) supports |
| 74 | +the linux CEC framework. |
| 75 | + |
| 76 | +If you want to get the CEC specification, then look at the References of |
| 77 | +the HDMI wikipedia page: https://en.wikipedia.org/wiki/HDMI. CEC is part |
| 78 | +of the HDMI specification. HDMI 1.3 is freely available (very similar to |
| 79 | +HDMI 1.4 w.r.t. CEC) and should be good enough for most things. |
| 80 | + |
| 81 | + |
| 82 | +DisplayPort to HDMI Adapters with working CEC |
| 83 | +============================================= |
| 84 | + |
| 85 | +Background: most adapters do not support the CEC Tunneling feature, |
| 86 | +and of those that do many did not actually connect the CEC pin. |
| 87 | +Unfortunately, this means that while a CEC device is created, it |
| 88 | +is actually all alone in the world and will never be able to see other |
| 89 | +CEC devices. |
| 90 | + |
| 91 | +This is a list of known working adapters that have CEC Tunneling AND |
| 92 | +that properly connected the CEC pin. If you find adapters that work |
| 93 | +but are not in this list, then drop me a note. |
| 94 | + |
| 95 | +To test: hook up your DP-to-HDMI adapter to a CEC capable device |
| 96 | +(typically a TV), then run:: |
| 97 | + |
| 98 | + cec-ctl --playback # Configure the PC as a CEC Playback device |
| 99 | + cec-ctl -S # Show the CEC topology |
| 100 | + |
| 101 | +The ``cec-ctl -S`` command should show at least two CEC devices, |
| 102 | +ourselves and the CEC device you are connected to (i.e. typically the TV). |
| 103 | + |
| 104 | +General note: I have only seen this work with the Parade PS175, PS176 and |
| 105 | +PS186 chipsets and the MegaChips 2900. While MegaChips 28x0 claims CEC support, |
| 106 | +I have never seen it work. |
| 107 | + |
| 108 | +USB-C to HDMI |
| 109 | +------------- |
| 110 | + |
| 111 | +Samsung Multiport Adapter EE-PW700: https://www.samsung.com/ie/support/model/EE-PW700BBEGWW/ |
| 112 | + |
| 113 | +Kramer ADC-U31C/HF: https://www.kramerav.com/product/ADC-U31C/HF |
| 114 | + |
| 115 | +Club3D CAC-2504: https://www.club-3d.com/en/detail/2449/usb_3.1_type_c_to_hdmi_2.0_uhd_4k_60hz_active_adapter/ |
| 116 | + |
| 117 | +DisplayPort to HDMI |
| 118 | +------------------- |
| 119 | + |
| 120 | +Club3D CAC-1080: https://www.club-3d.com/en/detail/2442/displayport_1.4_to_hdmi_2.0b_hdr/ |
| 121 | + |
| 122 | +CableCreation (SKU: CD0712): https://www.cablecreation.com/products/active-displayport-to-hdmi-adapter-4k-hdr |
| 123 | + |
| 124 | +HP DisplayPort to HDMI True 4k Adapter (P/N 2JA63AA): https://www.hp.com/us-en/shop/pdp/hp-displayport-to-hdmi-true-4k-adapter |
| 125 | + |
| 126 | +Mini-DisplayPort to HDMI |
| 127 | +------------------------ |
| 128 | + |
| 129 | +Club3D CAC-1180: https://www.club-3d.com/en/detail/2443/mini_displayport_1.4_to_hdmi_2.0b_hdr/ |
| 130 | + |
| 131 | +Note that passive adapters will never work, you need an active adapter. |
| 132 | + |
| 133 | +The Club3D adapters in this list are all MegaChips 2900 based. Other Club3D adapters |
| 134 | +are PS176 based and do NOT have the CEC pin hooked up, so only the three Club3D |
| 135 | +adapters above are known to work. |
| 136 | + |
| 137 | +I suspect that MegaChips 2900 based designs in general are likely to work |
| 138 | +whereas with the PS176 it is more hit-and-miss (mostly miss). The PS186 is |
| 139 | +likely to have the CEC pin hooked up, it looks like they changed the reference |
| 140 | +design for that chipset. |
| 141 | + |
| 142 | + |
| 143 | +USB CEC Dongles |
| 144 | +=============== |
| 145 | + |
| 146 | +These dongles appear as ``/dev/ttyACMX`` devices and need the ``inputattach`` |
| 147 | +utility to create the ``/dev/cecX`` devices. Support for the Pulse-Eight |
| 148 | +has been added to ``inputattach`` 1.6.0. Support for the Rainshadow Tech has |
| 149 | +been added to ``inputattach`` 1.6.1. |
| 150 | + |
| 151 | +You also need udev rules to automatically start systemd services:: |
| 152 | + |
| 153 | + SUBSYSTEM=="tty", KERNEL=="ttyACM[0-9]*", ATTRS{idVendor}=="2548", ATTRS{idProduct}=="1002", ACTION=="add", TAG+="systemd", ENV{SYSTEMD_WANTS}+="pulse8-cec-inputattach@%k.service" |
| 154 | + SUBSYSTEM=="tty", KERNEL=="ttyACM[0-9]*", ATTRS{idVendor}=="2548", ATTRS{idProduct}=="1001", ACTION=="add", TAG+="systemd", ENV{SYSTEMD_WANTS}+="pulse8-cec-inputattach@%k.service" |
| 155 | + SUBSYSTEM=="tty", KERNEL=="ttyACM[0-9]*", ATTRS{idVendor}=="04d8", ATTRS{idProduct}=="ff59", ACTION=="add", TAG+="systemd", ENV{SYSTEMD_WANTS}+="rainshadow-cec-inputattach@%k.service" |
| 156 | + |
| 157 | +and these systemd services: |
| 158 | + |
| 159 | +For Pulse-Eight make /lib/systemd/system/ [email protected]:: |
| 160 | + |
| 161 | + [Unit] |
| 162 | + Description=inputattach for pulse8-cec device on %I |
| 163 | + |
| 164 | + [Service] |
| 165 | + Type=simple |
| 166 | + ExecStart=/usr/bin/inputattach --pulse8-cec /dev/%I |
| 167 | + |
| 168 | +For the RainShadow Tech make /lib/systemd/system/ [email protected]:: |
| 169 | + |
| 170 | + [Unit] |
| 171 | + Description=inputattach for rainshadow-cec device on %I |
| 172 | + |
| 173 | + [Service] |
| 174 | + Type=simple |
| 175 | + ExecStart=/usr/bin/inputattach --rainshadow-cec /dev/%I |
| 176 | + |
| 177 | + |
| 178 | +For proper suspend/resume support create: /lib/systemd/system/restart-cec-inputattach.service:: |
| 179 | + |
| 180 | + [Unit] |
| 181 | + Description=restart inputattach for cec devices |
| 182 | + After=suspend.target |
| 183 | + |
| 184 | + [Service] |
| 185 | + Type=forking |
| 186 | + ExecStart=/bin/bash -c 'for d in /dev/serial/by-id/usb-Pulse-Eight*; do /usr/bin/inputattach --daemon --pulse8-cec $d; done; for d in /dev/serial/by-id/usb-RainShadow_Tech*; do /usr/bin/inputattach --daemon --rainshadow-cec $d; done' |
| 187 | + |
| 188 | + [Install] |
| 189 | + WantedBy=suspend.target |
| 190 | + |
| 191 | +And run ``systemctl enable restart-cec-inputattach``. |
| 192 | + |
| 193 | +To automatically set the physical address of the CEC device whenever the |
| 194 | +EDID changes, you can use ``cec-ctl`` with the ``-E`` option:: |
| 195 | + |
| 196 | + cec-ctl -E /sys/class/drm/card0-DP-1/edid |
| 197 | + |
| 198 | +This assumes the dongle is connected to the card0-DP-1 output (``xrandr`` will tell |
| 199 | +you which output is used) and it will poll for changes to the EDID and update |
| 200 | +the Physical Address whenever they occur. |
| 201 | + |
| 202 | +To automatically run this command you can use cron. Edit crontab with |
| 203 | +``crontab -e`` and add this line:: |
| 204 | + |
| 205 | + @reboot /usr/local/bin/cec-ctl -E /sys/class/drm/card0-DP-1/edid |
| 206 | + |
| 207 | +This only works for display drivers that expose the EDID in ``/sys/class/drm``, |
| 208 | +such as the i915 driver. |
| 209 | + |
| 210 | + |
| 211 | +CEC Without HPD |
| 212 | +=============== |
| 213 | + |
| 214 | +Some displays when in standby mode have no HDMI Hotplug Detect signal, but |
| 215 | +CEC is still enabled so connected devices can send an <Image View On> CEC |
| 216 | +message in order to wake up such displays. Unfortunately, not all CEC |
| 217 | +adapters can support this. An example is the Odroid-U3 SBC that has a |
| 218 | +level-shifter that is powered off when the HPD signal is low, thus |
| 219 | +blocking the CEC pin. Even though the SoC can use CEC without a HPD, |
| 220 | +the level-shifter will prevent this from functioning. |
| 221 | + |
| 222 | +There is a CEC capability flag to signal this: ``CEC_CAP_NEEDS_HPD``. |
| 223 | +If set, then the hardware cannot wake up displays with this behavior. |
| 224 | + |
| 225 | +Note for CEC application implementers: the <Image View On> message must |
| 226 | +be the first message you send, don't send any other messages before. |
| 227 | +Certain very bad but unfortunately not uncommon CEC implementations |
| 228 | +get very confused if they receive anything else but this message and |
| 229 | +they won't wake up. |
| 230 | + |
| 231 | +When writing a driver it can be tricky to test this. There are two |
| 232 | +ways to do this: |
| 233 | + |
| 234 | +1) Get a Pulse-Eight USB CEC dongle, connect an HDMI cable from your |
| 235 | + device to the Pulse-Eight, but do not connect the Pulse-Eight to |
| 236 | + the display. |
| 237 | + |
| 238 | + Now configure the Pulse-Eight dongle:: |
| 239 | + |
| 240 | + cec-ctl -p0.0.0.0 --tv |
| 241 | + |
| 242 | + and start monitoring:: |
| 243 | + |
| 244 | + sudo cec-ctl -M |
| 245 | + |
| 246 | + On the device you are testing run:: |
| 247 | + |
| 248 | + cec-ctl --playback |
| 249 | + |
| 250 | + It should report a physical address of f.f.f.f. Now run this |
| 251 | + command:: |
| 252 | + |
| 253 | + cec-ctl -t0 --image-view-on |
| 254 | + |
| 255 | + The Pulse-Eight should see the <Image View On> message. If not, |
| 256 | + then something (hardware and/or software) is preventing the CEC |
| 257 | + message from going out. |
| 258 | + |
| 259 | + To make sure you have the wiring correct just connect the |
| 260 | + Pulse-Eight to a CEC-enabled display and run the same command |
| 261 | + on your device: now there is a HPD, so you should see the command |
| 262 | + arriving at the Pulse-Eight. |
| 263 | + |
| 264 | +2) If you have another linux device supporting CEC without HPD, then |
| 265 | + you can just connect your device to that device. Yes, you can connect |
| 266 | + two HDMI outputs together. You won't have a HPD (which is what we |
| 267 | + want for this test), but the second device can monitor the CEC pin. |
| 268 | + |
| 269 | + Otherwise use the same commands as in 1. |
| 270 | + |
| 271 | +If CEC messages do not come through when there is no HPD, then you |
| 272 | +need to figure out why. Typically it is either a hardware restriction |
| 273 | +or the software powers off the CEC core when the HPD goes low. The |
| 274 | +first cannot be corrected of course, the second will likely required |
| 275 | +driver changes. |
| 276 | + |
| 277 | + |
| 278 | +Microcontrollers & CEC |
| 279 | +====================== |
| 280 | + |
| 281 | +We have seen some CEC implementations in displays that use a microcontroller |
| 282 | +to sample the bus. This does not have to be a problem, but some implementations |
| 283 | +have timing issues. This is hard to discover unless you can hook up a low-level |
| 284 | +CEC debugger (see the next section). |
| 285 | + |
| 286 | +You will see cases where the CEC transmitter holds the CEC line high or low for |
| 287 | +a longer time than is allowed. For directed messages this is not a problem since |
| 288 | +if that happens the message will not be Acked and it will be retransmitted. |
| 289 | +For broadcast messages no such mechanism exists. |
| 290 | + |
| 291 | +It's not clear what to do about this. It is probably wise to transmit some |
| 292 | +broadcast messages twice to reduce the chance of them being lost. Specifically |
| 293 | +<Standby> and <Active Source> are candidates for that. |
| 294 | + |
| 295 | + |
| 296 | +Making a CEC debugger |
| 297 | +===================== |
| 298 | + |
| 299 | +By using a Raspberry Pi 2B/3/4 and some cheap components you can make |
| 300 | +your own low-level CEC debugger. |
| 301 | + |
| 302 | +Here is a picture of my setup: |
| 303 | + |
| 304 | +https://hverkuil.home.xs4all.nl/rpi3-cec.jpg |
| 305 | + |
| 306 | +It's a Raspberry Pi 3 together with a breadboard and some breadboard wires: |
| 307 | + |
| 308 | +http://www.dx.com/p/diy-40p-male-to-female-male-to-male-female-to-female-dupont-line-wire-3pcs-356089#.WYLOOXWGN7I |
| 309 | + |
| 310 | +Finally on of these HDMI female-female passthrough connectors (full soldering type 1): |
| 311 | + |
| 312 | +https://elabbay.myshopify.com/collections/camera/products/hdmi-af-af-v1a-hdmi-type-a-female-to-hdmi-type-a-female-pass-through-adapter-breakout-board?variant=45533926147 |
| 313 | + |
| 314 | +We've tested this and it works up to 4kp30 (297 MHz). The quality is not high |
| 315 | +enough to pass-through 4kp60 (594 MHz). |
| 316 | + |
| 317 | +I also added an RTC and a breakout shield: |
| 318 | + |
| 319 | +https://www.amazon.com/Makerfire%C2%AE-Raspberry-Module-DS1307-Battery/dp/B00ZOXWHK4 |
| 320 | + |
| 321 | +https://www.dx.com/p/raspberry-pi-gpio-expansion-board-breadboard-easy-multiplexing-board-one-to-three-with-screw-for-raspberry-pi-2-3-b-b-2729992.html#.YGRCG0MzZ7I |
| 322 | + |
| 323 | +These two are not needed but they make life a bit easier. |
| 324 | + |
| 325 | +If you want to monitor the HPD line as well, then you need one of these |
| 326 | +level shifters: |
| 327 | + |
| 328 | +https://www.adafruit.com/product/757 |
| 329 | + |
| 330 | +(This is just where I got these components, there are many other places you |
| 331 | +can get similar things). |
| 332 | + |
| 333 | +The CEC pin of the HDMI connector needs to be connected to these pins: |
| 334 | +CE0/IO8 and CE1/IO7 (pull-up GPIOs). The (optional) HPD pin of the HDMI |
| 335 | +connector should be connected (via a level shifter to convert the 5V |
| 336 | +to 3.3V) to these pins: IO17 and IO27. The (optional) 5V pin of the HDMI |
| 337 | +connector should be connected (via a level shifter) to these pins: IO22 |
| 338 | +and IO24. Monitoring the HPD an 5V lines is not necessary, but it is helpful. |
| 339 | + |
| 340 | +This kernel patch will hook up the cec-gpio driver correctly to |
| 341 | +e.g. ``arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts``:: |
| 342 | + |
| 343 | + cec-gpio@7 { |
| 344 | + compatible = "cec-gpio"; |
| 345 | + cec-gpios = <&gpio 7 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>; |
| 346 | + hpd-gpios = <&gpio 17 GPIO_ACTIVE_HIGH>; |
| 347 | + v5-gpios = <&gpio 22 GPIO_ACTIVE_HIGH>; |
| 348 | + }; |
| 349 | + |
| 350 | + cec-gpio@8 { |
| 351 | + compatible = "cec-gpio"; |
| 352 | + cec-gpios = <&gpio 8 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>; |
| 353 | + hpd-gpios = <&gpio 27 GPIO_ACTIVE_HIGH>; |
| 354 | + v5-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>; |
| 355 | + }; |
| 356 | + |
| 357 | +This dts change will enable two cec GPIO devices: I typically use one to |
| 358 | +send/receive CEC commands and the other to monitor. If you monitor using |
| 359 | +an unconfigured CEC adapter then it will use GPIO interrupts which makes |
| 360 | +monitoring very accurate. |
| 361 | + |
| 362 | +The documentation on how to use the error injection is here: :ref:`cec_pin_error_inj`. |
| 363 | + |
| 364 | +``cec-ctl --monitor-pin`` will do low-level CEC bus sniffing and analysis. |
| 365 | +You can also store the CEC traffic to file using ``--store-pin`` and analyze |
| 366 | +it later using ``--analyze-pin``. |
| 367 | + |
| 368 | +You can also use this as a full-fledged CEC device by configuring it |
| 369 | +using ``cec-ctl --tv -p0.0.0.0`` or ``cec-ctl --playback -p1.0.0.0``. |
0 commit comments