I2c GPIO expander PCA9575 driver

Hi,

I would need to enable the kernel module for PCA9575 i2c gpio expander.

I tried to list the i2c devices with the i2c tool command line but the adress seems to not be present.

Should i enable the kernel module to be able to see it with i2cdetect please ?

Thanks a lot !

Hi, I’m the Toradex AI Assistant. I’m in early beta, and I would appreciate your feedback.
The Toradex Support team will follow up with you shortly!

Did you like my answer?

:+1: :-1:


Hello,

To enable the PCA9575 I2C GPIO expander and ensure it is visible with i2cdetect, you indeed need to make sure the kernel module for the PCA9575 is enabled. This involves configuring the kernel to include the driver for the PCA9575. If the driver is built as a module, it must be loaded into the kernel.

Here are the steps you can follow:

  1. Kernel Configuration: Ensure the kernel is configured to include the PCA9575 driver. This can be done by checking the kernel configuration (make menuconfig if you are customizing the kernel) under the I2C device drivers section. The PCA9575 might be listed directly or under GPIO expanders. If it’s not enabled, you would need to enable it (either built-in or as a module).

  2. Device Tree Configuration: For the PCA9575 to be recognized and properly initialized, you might need to add its definition to the device tree of your system. This involves specifying the I2C bus it is connected to and its address. You will need to edit the device tree source file (.dts) for your specific hardware configuration, adding a node for the PCA9575 under the I2C bus it is connected to.

Example device tree node:

&i2c1 {
    pca9575@20 {
        compatible = "nxp,pca9575";
        reg = <0x20>; // Address of the PCA9575 on the I2C bus
        gpio-controller;
        #gpio-cells = <2>;
    };
};

Replace &i2c1 with the actual I2C bus your PCA9575 is connected to, and 0x20 with the actual address of your device.

  1. Loading the Kernel Module: If the PCA9575 driver is built as a module, load it using modprobe command. For example, if the module name is pca9575, you would run sudo modprobe pca9575.

  2. Using i2cdetect: After ensuring the driver is enabled and the device is properly described in the device tree, you can use i2cdetect -y <bus_number> to scan for devices on the I2C bus. Replace <bus_number> with the number of the I2C bus your PCA9575 is connected to. If the device is properly connected and configured, it should now appear in the

Please, also check if these links can help you solve your problem:

I2C (Linux) | Toradex Developer Center.

It looks like this module is already integrated in the base images for am62:

torizon@verdin-am62-15190388:~$ zcat /proc/config.gz |grep PCA953X
CONFIG_GPIO_PCA953X=y
CONFIG_GPIO_PCA953X_IRQ=y

but when i list the kernel module mounted, it doesn’t appear.

torizon@verdin-am62-15190388:~$ lsmod        
Module                  Size  Used by
xt_conntrack           16384  3
xt_MASQUERADE          20480  3
nf_conntrack_netlink    49152  0
nfnetlink              20480  2 nf_conntrack_netlink
xfrm_user              49152  1
iptable_nat            16384  1
nf_nat                 49152  2 iptable_nat,xt_MASQUERADE
nf_conntrack          176128  4 xt_conntrack,nf_nat,nf_conntrack_netlink,xt_MASQUERADE
nf_defrag_ipv6         24576  1 nf_conntrack
nf_defrag_ipv4         16384  1 nf_conntrack
libcrc32c              16384  2 nf_conntrack,nf_nat
xt_addrtype            16384  2
iptable_filter         16384  1
ip_tables              32768  2 iptable_filter,iptable_nat
x_tables               53248  6 xt_conntrack,iptable_filter,xt_addrtype,ip_tables,iptable_nat,xt_MASQUERADE
br_netfilter           32768  0
bridge                258048  1 br_netfilter
stp                    16384  1 bridge
llc                    16384  2 bridge,stp
bnep                   32768  2
rpmsg_ctrl             16384  0
rpmsg_char             16384  1 rpmsg_ctrl
irq_pruss_intc         20480  0
pru_rproc              28672  0
overlay               139264  0
btnxpuart              28672  0
crct10dif_ce           16384  1
pvrsrvkm             1298432  0
ti_k3_r5_remoteproc    32768  0
virtio_rpmsg_bus       24576  0
rpmsg_ns               20480  1 virtio_rpmsg_bus
mwifiex_sdio           45056  0
ti_k3_m4_remoteproc    20480  0
mwifiex               282624  1 mwifiex_sdio
rtc_ti_k3              16384  1
ti_k3_common           20480  1 ti_k3_m4_remoteproc
cfg80211              905216  1 mwifiex
snd_soc_davinci_mcasp    36864  0
snd_soc_ti_udma        16384  1 snd_soc_davinci_mcasp
ti_ads1015             24576  0
snd_soc_ti_edma        16384  1 snd_soc_davinci_mcasp
snd_soc_ti_sdma        16384  1 snd_soc_davinci_mcasp
m_can_platform         20480  0
tidss                  81920  0
m_can                  36864  1 m_can_platform
mcrc                   16384  0
sa2ul                  45056  1
drm_dma_helper         20480  1 tidss
pruss                  20480  0
industrialio_triggered_buffer    16384  1 ti_ads1015
kfifo_buf              16384  1 industrialio_triggered_buffer
can_dev                45056  1 m_can
industrialio           98304  3 industrialio_triggered_buffer,kfifo_buf,ti_ads1015
snd_soc_nau8822        49152  0
tc358768               28672  0
lontium_lt8912b        20480  0
lm75                   28672  0
ina2xx                 20480  0
display_connector      20480  0
pwm_tiehrpwm           16384  0
spi_omap2_mcspi        28672  0
drm_kms_helper        188416  6 tc358768,drm_dma_helper,display_connector,lontium_lt8912b,tidss
syscopyarea            16384  1 drm_kms_helper
sysfillrect            16384  1 drm_kms_helper
sysimgblt              16384  1 drm_kms_helper
uio_pdrv_genirq        20480  0
fb_sys_fops            16384  1 drm_kms_helper
uio                    24576  1 uio_pdrv_genirq
libcomposite           73728  0
fuse                  131072  1

Greetings @FloSolio,

Should i enable the kernel module to be able to see it with i2cdetect please ?

Regardless of a kernel driver or not, you should be able to see the device at the respective i2c address with i2cdetect assuming everything has been connected properly.

but when i list the kernel module mounted, it doesn’t appear.

Note that the kernel config here is set to y. This means this kernel driver is built in and not built as a separate loadable kernel module. Therefore it would not show up via lsmod since this only lists loadable kernel modules. This just means the driver is compiled directly into the kernel.

Did you configure this device in the device tree yet? Otherwise the kernel driver here won’t automatically start managing this device. If you have done this and it’s still not working then do you see any logs from this driver via dmesg?

Best Regards,
Jeremias

1 Like

Hi Jeremias,

1. Test with current images

Here is the result of my i2cdetect. After looking at the datasheet, i realized that device adress was 0x20 so i see it here on i2c1:

I remark 0x20, it means the driver doesn’t know how to manage my device yet.
Same idea for 0x68 and 0x6c , two ADC MCP3428 on i2c3.

Related to pca953x in dmesg :

In this images, i can see that pca953x is, as you said, integrated in the image:

torizon@verdin-am62-15190388:/dev$ zcat /proc/config.gz | grep PCA9   
# CONFIG_I2C_MUX_PCA9541 is not set
CONFIG_I2C_MUX_PCA954x=y
CONFIG_GPIO_PCA953X=y
CONFIG_GPIO_PCA953X_IRQ=y
# CONFIG_GPIO_PCA9570 is not set
CONFIG_REGULATOR_PCA9450=y
CONFIG_LEDS_PCA9532=m
# CONFIG_LEDS_PCA9532_GPIO is not set
# CONFIG_LEDS_PCA955X is not set
CONFIG_LEDS_PCA963X=m
CONFIG_PWM_PCA9685=m

Try to deploy my custom dts overlay in the current image ( Device Tree Overlays on Torizon | Toradex Developer Center ) .

  • cat /proc/cmdline to get OSTree number
  • Get available overlay into current image:
  • Create my dts file there :
    sudo nano solimate-mb-v1.0.0.dts
  • Add it in overlays.txt
    cat overlays.txt
    fdt_overlays=verdin-am62_dsi-to-hdmi_overlay.dtbo verdin-am62_spidev_overlay.dtbo solimate-mb-v1.0.0.dts
  • sudo reboot
    :see_no_evil: :pray: :pray: :pray: :pray: :pray:

image

Still 0x20, so seems to not work…

I have some concern about name in the dts: main_i2c1. When I list /dev, i see i2c-1 but no main_i2c1. There is also verdin-i2c1 This is a bit confusing.

2. Generate my own custom images with custom dts.

I took into account your remark and restart from scratch by logging all my actions.
I folowed most of the steps from here: TorizonCore Builder Tool - Customizing Torizon OS Images | Toradex Developer Center

Here, what i have done and understood:

Setup build env:

- Created a new tcbdir folder

  • Download tcb-env-setup.sh
  • Source tcb-env-setup.sh
  • Create a new test directory, go in it
  • Create a new image template with torizon-builder build --create-template
  • Download torizon-core-docker-verdin-am62-Tezi_6.6.1+build.14.tar
  • Build image to test : Ok.

Add pca9575 device tree

  • Download linux and device-tree folder
  • Execute find linux -name “am62-verdin*.dts”
    → I need : linux/arch/arm64/boot/dts/ti/k3-am625-verdin-wifi-mallow.dts
  • List available overlay for my configuration with :
flo@linux:~/tcbdir/image_mb_v1.0.0$ torizoncore-builder dto list --device-tree linux/arch/arm64/boot/dts/ti/k3-am625-verdin-wifi-mallow.dts

Overlays compatible with device tree k3-am625-verdin-wifi-mallow.dts:
- device-trees/overlays/verdin-am62_dsi-to-hdmi_overlay.dts
- device-trees/overlays/verdin-am62_dsi-to-lvds_panel-cap-touch-10inch-lvds_overlay.dts
- device-trees/overlays/verdin-am62_hmp_overlay.dts
- device-trees/overlays/verdin-am62_mezzanine_panel-cap-touch-10inch-lvds_overlay.dts
- device-trees/overlays/verdin-am62_mezzanine_panel-lvds-dual-channel-1080p_overlay.dts
- device-trees/overlays/verdin-am62_nau8822-btl_overlay.dts
- device-trees/overlays/verdin-am62_ov5640_overlay.dts
- device-trees/overlays/verdin-am62_panel-cap-touch-10inch-dsi_overlay.dts
- device-trees/overlays/verdin-am62_panel-cap-touch-10inch-lvds_overlay.dts
- device-trees/overlays/verdin-am62_spidev_overlay.dts
  • Copy verdin-am62_dsi-to-hdmi_overlay.dts and modify it :
// MB V1.0.0

/dts-v1/;
/plugin/;

#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>

/ {
	compatible = "toradex,verdin-am62";
};


/* Verdin I2C_1 */
&main_i2c1 {
    pca9575@20 {
        compatible = "nxp,pca9575";
        reg = <0x20>; // Address of the PCA9575 on the I2C bus
        gpio-controller;
        #gpio-cells = <2>;
    };
};

Questions:

  1. Next step will be to deploy this image.
    But may be @jeremias.tx , you will pop up something obvious that i skipped with the onboard device tree activation?

  2. Even if the module is “y” for yes, how to play with these CONFIG_ options before build please (for futur purpose like my two adcs mcp3428)?

After looking at the dts file used in the image, i have found the corresponding aliases for i2c buses.

i2c1 is main_i2c1 so i’m pointing to the right buses.
I also note that the i2c1 is by defualt disable.

I try to add status=“okay”; in my dts and reboot.
Same issue, only 0x20 and not UU.

So i decided to deploy my new image as hot dts integration seems to have no impact.

  • torizoncore-builder images unpack torizon-core-docker-verdin-am62-Tezi_6.6.1+build.14.CUSTOM

  • torizoncore-builder deploy --remote-host 192.168.0.132 --remote-username torizon --remote-password … --reboot

After reboot, i ran i2cdetect -r -y 1.

Now I have UU for 0x20

image

And i can see a new gpiochip3 appearing.

image

I don’t know yet why it was not taken into account, and why i needed to deploy the new image.
Another strange thing is that this deployement was quiet fast ( 15sec may be) and i kept history of action.

I have doubt concerning the fact that it is really new images as some local folder and files are still present.

Next step will be to toggle the 8 pins of my pca9575.

To do so, I run the Toradex Gpio Docker:

  • docker run --rm -it -v /dev:/dev --device-cgroup-rule=‘c 254:* rmw’ torizonextras/arm64v8-gpiod
    With gpioinfo, i can see that my gpiochip should be gpiochip0, as no name have been given to the 16pins available.
    image

I try to set the first pin:

  • gpioset 0 0=1

Bingo my led switch on !
The same for the seven others. I’m really happy, my custom hardware is working after month of developpement. It is the first step but it is encouraging as it is my fist linux system :slight_smile: .

Next step will be to fine tune the details like, understood if it is working because of the new image or just because it has reboot ( even if I tried before two times without sucess). It seems that flashing new image via ssh doesn’t erase the full memory or may be I’m wrong…

Next will be to implement the mcp3428 adc but let’s open another ticket may be :sweat_smile: :joy: .

I’m glad to see you were able to get this resolved. Let me just address some of your open questions/confusions.

Try to deploy my custom dts overlay in the current image

First of all what you did here is not correct. You just created a text file you didn’t actually create an overlay. A device tree overlay needs to be compiled into a binary. you can’t just make a text file and have that be usable as is. This is explained in the device tree overlay article that you are referencing.

Even if the module is “y” for yes, how to play with these CONFIG_ options before build please (for futur purpose like my two adcs mcp3428)?

To change kernel configuration options requires to re-build the kernel in it’s entirety. This is a more involved task that TorizonCore Builder is not capable of. You would need to build a new image with kernel customizations with Yocto: Build Torizon OS from Source With Yocto Project/OpenEmbedded | Toradex Developer Center

You could also request that we set this kernel config. In which case we’ll set it as m for a loadable kernel module. Then in future images you can test it. However, with this method we simply just enable the kernel config we don’t do any testing of it, this would still be your responsibility.

I don’t know yet why it was not taken into account, and why i needed to deploy the new image.
Another strange thing is that this deployement was quiet fast ( 15sec may be) and i kept history of action.

I don’t understand what you meant by “hot dts integration”, so it’s not really clear to me what you did the first time.

Also when you use TorizonCore Builder to deploy over network it does so via OSTree. OSTree only deploys the differences since last time so subseqent deployments should technically be faster.

I have doubt concerning the fact that it is really new images as some local folder and files are still present.

It’s not technically a new image. Again you just deployed your changes with OSTree via TorizonCore Builder. OSTree does not affect every file on the system the same way, so that is probably why you noticed some folders and files still present. I would highly suggest reading on how OSTree works as it’s a bit much for me to go into detail here in this thread: OSTree | Toradex Developer Center

Next will be to implement the mcp3428 adc but let’s open another ticket may be

Yes that would be preferable as to keep the topics here separate and organized.

Best Regards,
Jeremias

Ok,

Thanks a lot @jeremias.tx , I didn’t know this OSTree tool, as it is in the "In depth " categorie of the documentation. But is is a good sign, it means I start to have a better understanding of the whole system.

I understood from documentation that two method were available:
with or without building the image.
Approach 1, without by adding my dts and updates overlays.txt
Approach 2: update tcbuild.yaml and rebuild images with torizonbuilder

Its is mentionne like this in the doc :

There are different phases of development with different methods for customizing Torizon OS with device tree overlays:

By hot dts integration, I wanted to point to the first technic, meaning to add dts and update overlays.txt in the board directly, without compiling it. So it was not working, and that’s normal, because it was not compiled.
The second time, I updated my tcbuild.yaml to add this dts, build my new image with torizonbuilder build, and i have seen in the log that it check compatibility of the my dts with others. After reboot, it was working.

I think i will read again the full documentation page on the topic.

At least i have something working to continue my development.

Thanks a lot !

Glad I was able to help clarify some things for you. If you have any further questions or issues feel free to open new topics threads here on our community.

Best Regards,
Jeremias

1 Like