Verdin Development Board -- driver for rotary encoder

Hello,

I would like to make a 62S11-M5-100CH rotary encoder, work together with a qt creator app. I would like to know if there is any driver to work on the verdin development board? If not, what can I do to make the encoder work? Thank you very much for your attention!

Hi @allanbic ,

The QT Creator is an IDE used to develop your application, the easiest way to achieve what you want is to use a driver to make the communication between the Encoder and the Kernel, doing this will make available the communication with the device through some interface, in your case, it will use GPIO, then after this, you can access the GPIOs that communicate with the Encoder on your Qt application.

For the communication between the Kernel and your device, please take a look at this NXP question. The question also points to a generic driver for the rotary encoder that you use as a starting point.

Best regards,
Daniel Morais

Hi, Daniel! How are you? Thanks for your answer. I’ll follow the step by step here and get back to you.

Daniel, will I have to generate a dts file and later generate a dtbo (binaries) file and put this file in the overlays directory and make the write in overlays.txt?

Hi @allanbic ,

Can you please share which OS are you using?

Yes, first of all, you will need to add the driver into the kernel and recompile it, you can check this article as a reference, about the device tree you could also make the changes into the device tree and recompile it alongside the kernel or create the device tree overlays.

Best regards,
Daniel Morais

I’m using Verdin-iMX8MM_Reference-Multimedia-Image-Tezi_5.5.0. Follow the procedure: Build a Reference Image with Yocto Project/OpenEmbedded | Toradex Developer Center.
I already have my application up and running and the SDK for QT has already been created.
I’m following the link step by step: Build U-Boot and Linux Kernel from Source Code | Toradex Developer Center, to generate the rotary_encoder.dtbo binary, however the system is asking me for some dependencies (#include) that I am not able to fix. Dependencies are related to dt-bindings. When I leave the .dts file with nothing written and generate the .dtbo, it works, but when the .dts file needs to be included, I always have errors in the generation. What to do?

Hi @allanbic ,

I believe you are a bit lost on the procedures, I will display below the steps you need to do to achieve what you want.

1 - Clone the Toradex kernel repository pointing to the correct branch based on your BSP, you can do this by following the instructions provided in this article.
2 - The rotary-encoder driver is already on our kernel sources, so you will need just to open the make menuconfig and configure it as a built-in or module, this will enable the driver on the kernel, after this you should recompile the kernel and substitute it into your image.
3 - The driver needs a way to know how to rotary-encoder will be connected to the system, you do this by adding a node into the device tree, the node should look as below:

    rotary-encoder {
        compatible = "rotary-encoder";
        status = "okay";
        gpios = <&gpio3 24 GPIO_ACTIVE_HIGH>, <&gpio3 25 GPIO_ACTIVE_HIGH>;
        linux,axis = <0>; /* REL_X */
        rotary-encoder,encoding = "gray";
        rotary-encoder,relative-axis;
    };

Where GPIO3_IO24 and GPIO3_IO25 are the GPIOs you will use on the hardware side. To find these values please check the module datasheet. The above configuration can be done by rebuilding the .dtb or through device tree overlays.

For more information about the device tree properties please check this file.

In my opinion, you should first do these changes directly on the kernel repository and then change the zImage (kernel binary) and the .dtb (device tree binary) into your image to test it and make it work. After this you can port these configurations to Yocto/OpenEmbedded to create a final image with it.

It should be enough to make the encoder work, but I don’t have one on my side to test it. I believe that after these configurations a device should be available under /dev/ on Linux and then you can use this device on your Qt application.

Best regards,
Daniel Morais

Daniel, would it be possible for toradex to include the rotary encoder driver in the Reference Multimidia Image with the pins already established?

Daniel, I followed the procedures, edited the imx8mm-verdin.dtsi file and added the code indicated above. I generated the zImage and device tree binaries. 4 .dtb binaries were generated, those shown in the reference image. Before all that, through the menuconfig command, I enabled the rotary encoder driver inside the kernel, in: Input Device Support -Miscellaneous Devices - Rotary Encoders…
However, when I migrate the files to the reference image folder and add and install it through the easy installer, the system does not work. I must be making some mistake in the process, what is it? The easy installer finishes the process, without errors, however when I ask to restart after the installation, the system doesn’t work!

Hi @allanbic ,

Do you have access to the debug serial port? If yes, can you check in which boot step the module is failing?

Before compiling the kernel, did you execute this configuration for the module?

If possible, please share with us the commands you executed.

Best regards,
Daniel Morais

Daniel, I don’t have access to the debug serial port. I did everything according to the tutorial, being:

Kernel Configuration

cd ~/workdir/linux-toradex

make toradex_defconfig

In make nconfig, I enabled the rotary encoder driver in the kernel, as explained above.

Then I generated the kernel (zImage) with the command:

make -j$(nproc) Image.gz 2>&1 | tee build.log

And I also generated the binaries:

make DTC_FLAGS=“-@” freescale/imx8mm-verdin-nonwifi-dahlia.dtb

make DTC_FLAGS=“-@” freescale/imx8mm-verdin-nonwifi-dev.dtb

make DTC_FLAGS=“-@” freescale/imx8mm-verdin-wifi-dahlia.dtb

make DTC_FLAGS=“-@” freescale/imx8mm-verdin-wifi-dev.dtb

Through this, the kernel image and also the .dtb binaries were generated. I did the direct replacement in the bootfs folder.

As explained earlier, before generating the .dev binaries, I edited the file: "imx8mm-verdin.dtsi and placed the code with the rotary encoder pin out.

rotary-encoder {
compatible = “rotary-encoder”;
status = “okay”;
gpios = <&gpio3 24 GPIO_ACTIVE_HIGH>, <&gpio3 25 GPIO_ACTIVE_HIGH>;
linux,axis = <0>; /* REL_X */
rotary-encoder,encoding = “gray”;
rotary-encoder,relative-axis;
};

Did I make a mistake in the process?

Daniel? can you help me?

Hi @allanbic,

Some considerations that can be useful for you:

  1. After enabling the encoder using nconfig, you can confirm this configuration with the command $ cat .config | grep ROTARY in the linux-toradex folder. If it is enabled, it will show “CONFIG_INPUT_GPIO_ROTARY_ENCODER=y”.

  2. The files deployed to the target are : Image.gz (related to kernel) in /linux-toradex/arch/arm64/boot folder and the imx8mm-verdin-nonwifi-dev.dtb (related to DT) file in /linux-toradex/arch/arm64/boot/dts/freescale folder into the /boot target folder. You can do this to do a fast development, just sending the binaries to the module through scp command as an example.

Note: The device tree loaded by default is imx8mm-verdin-nonwifi-dev.dtb.

  1. After doing the above changes into the image and having it boot, if you don’t compile the modules as explained here you must modify the kernel modules folder since we are generating a new kernel. To do this you can just rename the folder inside /lib/modules with the output of the uname -r command.

After deploying the new kernel and device tree to the image, you will be able to see the device coming up as an input device:

root# dmesg | grep rotary
[ 1.807659] rotary-encoder rotary@0: gray
[ 2.509539] rotary-encoder rotary@0: gray
[ 2.517032] input: rotary@0 as /devices/platform/rotary@0/input/input1

Your issue is probably related to the binaries substitution, please try to repeat the tests checking the comments above, and see if it works for you.

Best regards,
Daniel Morais

Hello, how are you, Daniel? Good night!
Daniel, first I will explain the reason for the error found earlier: I was putting the zImage and .dtb files directly in the Reference-Multimedia-Image-verdin-imx8mm.bootfs.tar.xz folder, before installing. Doing as you said, I was successful in installing the kernel and also binary.
Now I’m having a problem:
I edited the file - imx8mm-verdin-nonwifi-dev.dts and put the code:

rotary-encoder {
        compatible = "rotary-encoder";
        status = "okay";
        gpios = <&gpio3 24 GPIO_ACTIVE_HIGH>, <&gpio3 25 GPIO_ACTIVE_HIGH>;
        linux,axis = <0>; /* REL_X */
        rotary-encoder,encoding = "gray";
        rotary-encoder,relative-axis;
    };

Later I generated the binary and placed it in the /boot directory.
I gave the command dmesg | grep rotary and got as a response:

login as: root
root@verdin-imx8mm-06827388:~# dmesg | grep rotary
[    1.358356] rotary-encoder rotary-encoder: gray
[    2.703706] rotary-encoder rotary-encoder: gray
[    2.711940] rotary-encoder rotary-encoder: unable to get gpios: -16
[    2.721855] rotary-encoder: probe of rotary-encoder failed with error -16

What is the reason for the error?

Hi @allanbic ,

Good! It seems that the driver is now probing correct.

The issue is that the system can’t get the GPIOs you configured on the gpios parameter inside the device tree:

gpios = <&gpio3 24 GPIO_ACTIVE_HIGH>, <&gpio3 25 GPIO_ACTIVE_HIGH>;

On the above example it’s being requested the GPIO3_IO24 and the GPIO3_IO25, are these the GPIOs you will use?

In this case, you need to check which SODIMM pins you will connect to the encoder on the hardware side, check which GPIOs these pins are related to (you can check this on the topic 4.4 Functions List on the module datasheet), and then configure it on the device tree.

Please let me know if you need further help.

Best regards,
Daniel Morais

Hi, Daniel, how are you? Thanks for your answer. It got even more confused in my head… I analyzed the datasheet and saw that all the pins already have a function. In this case I wanted to use SODIMM_196 and SODIMM_198, but I don’t know how to find their respective gpio, taking into account topic 4.4. I apologize for the inconvenience!

Hi @allanbic ,

In your case you have to take a look into the table of the topic 4.4 SoC Functions List, searching for the pins 196 and 198 you can find the functions GPIO5.IO[10] and GPIO5.IO[12] respectively, these are the values you should insert into your rotary-encoder node.

Since these two pins are used by the ECSPI as standard, you should also disable the previous function and add a new one, to help you with this I created a small patch that does the needed changes.
enable-rotary-encoder-imx8mm.patch (1.2 KB)

Can you please apply this patch on your device tree and check if it works?

Please let me know if you need any help.

Best regards,
Daniel Morais

Hi, Daniel, how are you?
Daniel, to not use the patch, which pins do you recommend using? Can I use pins (218) → GPIO1_IO11 and (220) → GPIO1_IO08. Both pins are gpios at alt0.
I did a test with the pins above, the system found the gpios:

login as: root
root@verdin-imx8mm-06827388:~# dmesg | grep rotary
[    1.360476] rotary-encoder rotary@0: gray
[    2.728617] rotary-encoder rotary@0: gray
[    2.736646] input: rotary@0 as /devices/platform/rotary@0/input/input1

But the encoder is not working yet, I have put the pullup resistors.
Just to confirm, if I receive the above messages, does this imply that I can already use the encoder?

Daniel, I apply the patch " " and I have the problem:

[    1.357442] rotary-encoder rotary-encoder: gray
[    2.735102] rotary-encoder rotary-encoder: gray
[    2.743682] input: rotary-encoder as /devices/platform/rotary-encoder/input/input1
[    2.826018] imx8mm-pinctrl 30330000.pinctrl: pin MX8MM_IOMUXC_ECSPI2_SCLK already requested by rotary-encoder; cannot claim for 30830000.spi

what do I do now?

Hi @allanbic ,

Sorry, I missed a configuration on another file, please try this patch.
enable-rotary-encoder-imx8mm.patch (1.7 KB)

I made a small test here and everything worked fine, see below:

root@verdin-imx8mm-06827384:~# dmesg | grep rotary
[ 1.358872] rotary-encoder rotary-encoder: gray
[ 2.251047] rotary-encoder rotary-encoder: gray
[ 2.256628] input: rotary-encoder as /devices/platform/rotary-encoder/input/input1
root@verdin-imx8mm-06827384:~# ls -l /dev/input/event1
crw-rw---- 1 root input 13, 65 Mar 24 18:58 /dev/input/event1

Best regards,
Daniel Morais