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