i.MX6 CEC

Introduction

According to wikipedia definition : “Consumer Electronics Control (CEC) is an HDMI feature designed to allow the user to command and control up-to 15 CEC-enabled devices, that are connected through HDMI by using only one of their remote controls (for example by controlling a television set, set-top box, and DVD player using only the remote control of the TV). CEC also allows for individual CEC-enabled devices to command and control each other without user intervention.
It is a one-wire bidirectional serial bus that is based on the CENELEC standard AV.link protocol to perform remote control functions.”
Since the Eden release XBMC has support for CEC thanks to libCEC. Besides the freescale i.MX6 SOC is able to handle this bus by itself : There is no need to buy an additional USB device such as this one.
Unfortunately, so far, nobody publicly added i.MX6 CEC support in libCEC. It was a shame and I decided to address this issue.

Development

While developing this missing part, I had to tackle 3 tasks :

  • Finding a hardware platform to develop and test this feature
  • Adding support in libCEC
  • Solving issues with the CEC driver itself

The first item may seem trivial but it is not. Indeed, many iMX6 products/boards do not properly wire the CEC signal.
Here are the info I gathered :

  • Wandboard was reported by a user to have CEC signal unconnected in this comment which refers to wandboard forums
    Edit (october, 12): After lots of comments, I confirm that no wandboard version is properly wired to use CEC (At this time at least). But if you have a wandboard quad and are able to use a soldering iron, then have a look at this thread
  • GK802 is no longer of interest to me : It is a device with no engineering support nor official technical data. It is not properly cooled. It has a very attractive price but, as a developer, I lost enough time with it. CEC signal may be connected or not, I don’t care as I know I will have no resource to understand what happens if it does not work…
  • I also know that nitrogen6x (I don’t own that board by myself) from boundary devices does not expose the CEC signal (thanks to this comment)
  • My utilite pro would have been a perfect device to test CEC. Unfortunately, my device comes from an early batch which was not properly wired (while currently produced devices are all good).

So, at the end, finding the right device for this development was not so easy. Fortunately compulab was kind enough to send me a new utilite from their new batch (and a properly wired CEC signal). I am about to publish a XBMC image with CEC support for utilite as a way to thank them for their support.

Then adding support for a new adapter in libCEC was not so hard : The code is well structured and there is obviously a provision to add new devices.
At some stage, I found that support for existing devices was a little cumbersome but I finally understood that the real culprit was not libCEC but the interface with underlying hardware and that I was able to have a simpler implementation as long as the driver allows for it. Note that, for now, I have not added support to handle several logical addresses at the same time (The hardware allows for it but there is not yet support in the driver for this)

And so we come to the third item : The CEC kernel driver. Freescale provides this driver but I was a little surprised of the current state of this driver (in the their BSP V4.0.0 or V4.1.0). It is supposed to be a simple character device (which is just fine) but I found quite a few shortcomings.

  • First they don’t care about being compliant with the well known POSIX interface :
    The read syscall will immediately return if no data is available even if the device is not opened with the O_NONBLOCK flag.
    This same read syscall will return a false value (ie not the effective number of bytes seen by userspace)
    The write syscall will return 0 if successful while it should return the number of written bytes
    The poll syscall will never state that the device is writable
  • Then they do not properly release the IRQ when the kernel module is unloaded (because of this, you will not be able to reload the module a second time)
  • At last, they use locking in a sometime hazardous way and even copy/paste comments from “vpu” in this driver…

As a conclusion, this driver has not been very carefully developed and is misleading when you try to use it at first time.
But I don’t blame freescale for this : At least they release this driver and, that way, they allow to enhance it. All the more as they also provide an excellent reference manual which describes very well the hardware interface.
So I had to solve the afforded mentioned items in order to use it smoothly from libCEC.

Final thoughts

At the end, I rebuilt XBMC with CEC support and was able to give it a try faced to my panasonic PZ81 TV.
And… it works just fine !
I am able to browse XBMC GUI with my TV remote.
I have already published my changes for libCEC here and will try to mainline them.
Changes for the kernel driver should be released next week.
[Edit : A first (still wip) patch is now public]
Last but not least, all this work is useful only if a product can take advantage of it. So here is a XBMC image which provides XBMC with CEC support targeted at utilite here.

Edit 2014/03/13 : I have moved iMX6 libcec to xbmc-imx6. Enhancement and bug tracking can occur here starting from now…
Edit 2014/04/28 : Other important fixes and port to 3.10 kernel are here

35 thoughts on “i.MX6 CEC

  1. Pingback: XBMC for utilite (CEC support included) | Stephan's blog

  2. Stephan

    I’ve just looked at the published user guides which show the wandboard schematics. I compared the solo/dual to the Quad wandboard rev b1 schematics and from what I can see the CEC signal is available on the HDMI connector pin 13 for both boards. However If you compare the two sets of schematics the solo/dual processor board does not have the CEC signal present on the Expansion connector J1A but the signal does seem to be present on the J1A connector of the Quad wandboard. I’m not sure if he was speaking from a position of authority but perhaps the author linked to above was referring to the solo/dual.

    Maybe someone else can take a look.

    • Hi
      I just had a careful look.
      You are right, on quad, the CEC signal is wired from HDMI connector to J1A.
      But then I don’t understand on the carrier board : The pin 71 from J1A should be connected to imx6 KEY_ROW2 or EIM_A25 pin and it does not seem to be the case …
      Another user wrote a mail and he says that only a resistance is missing but I don’t understand as to me there is no chance to get it work if the CEC signal is not connected to one of the 2 pins I quote…
      Anyway stay tuned for updates or findings…

      Regards

        • Hi leslie,

          Thanks for the update I should have an old schematics as I still cannot see how the hell the CEC signal will end on the right imx pin (that is KEY_ROW2 or EIM_A25) . As far as I can see EIM_A25 is used as a GPIO to enable wifi and KEY_ROW2 is on a test point (TP78) ! The pin 71from J1A can be connected through a 0 Resistance to EIM_DA2 which is NOT a valid pin to connect CEC to iMX6Q.
          I can not provide anything on my side until I have a real explanation…
          Best regards
          Stephan

          • Stephan

            Yeh when I looked again I couldn’t really see where you made the link between KEY_ROW2 or EIM_A25.

            FYI I went ahead and soldered R405. dmesg | grep CEC is showing me ‘HDMI CEC initialized’. I didn’t check to see if it was there before I soldered the link so don’t really know if its a rouge message.

            • I assume that the ‘HDMI CEC initialized’ means that kernel support is already enabled. Would I be wasting my time if I tried to extract the files from the utilite image. ?

            • Leslie, You cannot connect the CEC signal where you want. You have to respect the iMX6 Reference Manual (IMX6DQRM.pdf document available on freescale website) which states which pins can be used. In this document p322, you can see that HDMI_TX_CEC_LINE can be connected to KEY_ROW2 or EIM_A25 (and that you have to configure IOMUX accordingly). If it is not then it will not function. that’s it.
              Your kernel message means nothing at a physical level : It only means that the driver is loaded… This evening I will send to you my modified driver if you wish but don’t expect it to work without proper iomux configuration nor proper wiring on correct pin of course…
              Regards
              Stephan

              • Hi
                Stephan,
                what we could do is to wire the TP78 to the pad of the unsoldered R405 which leads to pin 13 HDMI and follow the ref.manual.
                But where is the register set to choose KEY_ROW2?

                On the other hand, why would wandboard choose to route EMI_DA2 to the CEC pin13?
                An undocumented feature?
                Or perhaps not using the cec-engine of the soc and do bitbanging a gpio for the cec stuff?
                I opened a thread at the wandboard.org forum. perhaps the wandboard guys are willing to answer the question 🙂

                Meanwhile if you could provide a image where cec is correctly configured for KEY_ROW2, i will try to wire from TP78 to the restistorpad.
                regards Chris

                • > On the other hand, why would wandboard choose to route EMI_DA2 to the CEC pin13?

                  Why the Wandboard (and many others) routes the wrong CEC pin is likely because the Freescale sample schematics use the wrong pin.
                  Our hardware guy, happily unaware of any software limitations, just picked the same pin as Freescale.

                  /Tapani (wandboard.org)

              • Appreciate the clarification

                Seems the wandboard documentation does indeed differ from the freescale reference manual.

                Its a wait and see until wandboard come up with a response. Lets hope its sloppy documentation on their part.

                • Hi Leslie,

                  Please read the other comments and follow the link to wandboard forums. It is no longer a wait and see : The wandboard is not correct, that’s it.
                  So far, I have had 3 reports of users who are skilled enough to mod their board and wire it properly and who reported success with my modified libCEC and driver…

                  Regards

  3. Hi Stephan,
    does your XMBC with CEC support work with the pulse-eight usb adapter or exclusivly with the utilite hardware?
    Regards
    Chris

    • Hi Chris,

      There is no reason why the pulse-eight usb adapter would not work with my libCEC build I guess. But I have not tested it as I don’t own such an adapter…
      Also, note that my dev should work on any iMX6 device (not only utilite) as soon as the hw designers wire properly the CEC signal…

      Regards
      Stephan

  4. Hi

    Chris, your proposal makes sens.
    So you can find a new kernel for wandboard with my updated cec driver + iomux configuration for KEY_ROW2 here : https://stephan-rafin.net/owncloud/public.php?service=files&t=aca527f280223ff20741ec44ce1942ee
    Use it with the utilite RFS which is here : https://stephan-rafin.net/owncloud/public.php?service=files&t=e98c2d1bf60b9bedbf9c1f7c1f33cabf
    It should work if you mod your board the way you describe…
    Best regards
    Stephan

        • Hi Stephan
          After soldering on thursday, today i tried to put the Kernel and rfs together but with no luck.
          Wandboard boots up, shows a short flicker of the xbmc logo and then shuts down HDMI (tv says ‘no Input’).
          CEC however is working because tv Shows xbmc in the list of devices and when I shut down the tv, wandboard shuts down too.
          Heres my way i tried:
          Fortmat the ROOTFS Partition
          Untar the utilite rootfs on ROOTFS Partition
          mv uImage uImage_old
          cp new uImage to boot partition

          Have i done something wrong?
          If yes, can you tell me how to do or put it together in a complete image?
          regards
          Chris

          • Ok, found it:-)
            Xbmc was configured to be on tv hdmi1 but in my setup its hdmi2.
            Now it works.
            Is it somehow possible to wake up the wandboard from suspend?

              • Stephan

                Been distracted the last few days with the utilite, I wasn’t reluctant to believe that you were right was just so so eager for this to work. Hopefully wandboard can fix with the next revision of their board like the guys did at compulab.

                Now to get the soldering iron out and try the modified file.

                Very much appreciate you seeing this though.

                Regards
                Leslie

  5. HI,

    this is great. Can you tell me is there list devices(imx6) which support libcec?

    And are you have info about cubox-i?

  6. I got the new distro build with Yocto using your meta layer. Thanks!

    Have you tried playing videos using youtube plugin or any other video plugins? I get error URL resolve error.

    • Hi prabhu
      youtube addon works fine. Depending on the date of your build, you may need to install the packages python-json and python-subprocess (with smart for instance)
      Stephan

  7. Hi Stephan;

    I am impressed with your work and if I understand it right it would be perfect for a project I have.

    Specifically I need a computer that can run Android and work with google+ hangouts and have a working cec interface and supporting drivers/libraries. I hope to send and receive cec commands (either terminal, python or java) on pin 13 to interact with cec compliant devices but do not require a broad instruction set (e.g. mostly routing control). I have worked with the pulse-eight product but it does not support Android and in any case should not be required if the computer will communicate properly with the cec on the hdmi port.

    Do I understand it correctly that your work in combination with a Utilite computer can achieve this?

    Thank you for your assistance.

    Ted

  8. Pingback: Cheap IR receiver | Stephan's blog

  9. Hi i was trying to use your patched version of libcec on a Cubox-i. But I have some troubles with it.
    http://imx.solid-run.com/forums/viewtopic.php?f=16&t=6&hilit=libcec

    when i execute make shows an error:
    /home/linaro/libcec/src/lib/platform/util/StdString.h:1605:14: note: the mangling of ‘va_list’ has changed in GCC 4.4
    adapter/IMX/IMXCECAdapterCommunication.cpp: In member function ‘virtual bool CEC::CIMXCECAdapterCommunication::SetLogicalAddresses(const cec_logical_addresses&)’:
    adapter/IMX/IMXCECAdapterCommunication.cpp:226:59: error: invalid conversion from ‘int’ to ‘void*’ [-fpermissive]
    /home/linaro/libcec/src/lib/platform/sockets/cdevsocket.h:95:19: error: initializing argument 2 of ‘virtual int PLATFORM::CCDevSocket::Ioctl(int, void*)’ [-fpermissive]

    I’m using Solid Run’s Linaro/Ubuntu 11.04 image for cubox-i.

    Regards.

  10. Hi,

    Bit late but I just wanted to inform you that I was able to get CEC working on Nitrogen6x board with your modified HDMI CEC driver. I just had to map KEY_ROW2 pin for CEC which is used for CAN bus on Nitrogen6x. I removed a resistor R304 and soldered a wire from the pad to HDMI connector pin 13. Of course CAN bus cannot be used anymore. The EIM_A25 is not connected at all so it cannot be used.

    Now I am running a QT 5 QML app on Nitrogen6x which I can now control with my TV remote via HDMI. Sweet…

  11. HI

    I have a custom board with IMX6Q , in which I am trying to use the HDMI CEC

    Bellow mentioned are my configurations :

    Device tree

    pinctrl_hdmi_cec: hdmicecgrp {
    fsl,pins = ;
    };

    &hdmi_cec {
    pinctrl-names = “default”;
    pinctrl-0 = ;
    status = “okay”;
    };

    Kernel version : 4.9.123

    Application tried both freescale’s unit test application and the cec-client with both I find the bellow observation

    When probed I see the data in the CEC line , but no response from the TV, On further debugging found the the timing between the CMD pulse is 2.7ms which is violating the CEC spec of 3.6ms -3.8ms.

    Any help why the data is not in the correct timing.

    I tried the above test with a different custom board which has IMX6SOLO , Same configuration, same Kernel, The CEC works with IMX6SOLO, I am able to query the CEC version of the same TV used with IMX6Q board

    surprisingly the timing here matches CEC SPEC, which is 3.6ms.

    Silicon version of the IMX6Q : 1.5

    Can anyone help me with this issue,

    Thanks and regards

    Terry

Leave a Reply

Your email address will not be published. Required fields are marked *