Patching the MCP23017 kernel driver device tree to work with hal_gpio (RPi)

More
28 Dec 2023 13:33 - 28 Dec 2023 21:18 #289244 by jst
tldr: The following procedure should work for any SPI/I2C/... GPIO Expander with an existend linux kernel/gpiod driver that uses a Device Tree configuration.

I'm currently retrofitting a small CNC mill with LinuxCNC on the Raspberry Pi 4.
To get more GPIOs I wanted to use the MCP23017 I2C Port Expander (www.microchip.com/en-us/product/mcp23017).
For testing I use this board: www.adafruit.com/product/4132
I don't expect the GPIOs to be realtime, but I want to use them in a HAL file.

While resaerching I found this thread (but there is no real solution, only some hints): forum.linuxcnc.org/24-hal-components/464...dapt-the-extended-io
I also took a closer look at the hal_gpio driver.

As documented the hal_gpio driver relies on the gpiod package and the names given by gpioinfo. I was lucky because there is a linux kernel driver for the MCP23017:
github.com/torvalds/linux/blob/master/Do...pinctrl-mcp23s08.txt
github.com/torvalds/linux/blob/master/dr...nctrl-mcp23s08_i2c.c

So I added the Device Tree (/boot/broadcom/overlays/mcp23017.dtbo) that was already provided in the firmware folder on the RPi to the config.txt as an overlay and did a reboot.
cnc@raspberrypi:~$ sudo nano /boot/broadcom/config.txt
 - add follwing at the end of the file:
dtoverlay=mcp23017
 - also enable I2C if not alredy enabled:
dtparam=i2c_arm=on

After running gpioinfo the GPIO extender with the pins was shown, but they didn't have a name ('unnamed').
cnc@raspberrypi:~$ gpioinfo
gpiochip0 - 58 lines:
        line   0:     "ID_SDA"       unused   input  active-high
        ...
        line  57: "RGMII_TXD3"       unused   input  active-high
gpiochip1 - 8 lines:
        line   0:      "BT_ON"       unused  output  active-high
        ...
        line   7:    "SD_OC_N"       unused   input  active-high
gpiochip2 - 16 lines:
        line   0:      unnamed       unused   input  active-high
        line   1:      unnamed       unused   input  active-high
        line   2:      unnamed       unused   input  active-high
        line   3:      unnamed       unused   input  active-high
        line   4:      unnamed       unused   input  active-high
        line   5:      unnamed       unused   input  active-high
        line   6:      unnamed       unused   input  active-high
        line   7:      unnamed       unused   input  active-high
        line   8:      unnamed       unused   input  active-high
        line   9:      unnamed       unused   input  active-high
        line  10:      unnamed       unused   input  active-high
        line  11:      unnamed       unused   input  active-high
        line  12:      unnamed       unused   input  active-high
        line  13:      unnamed       unused   input  active-high
        line  14:      unnamed       unused   input  active-high
        line  15:      unnamed       unused   input  active-high

After some resaech and comparison to the Raspberry Pi GPIO device tree I figured out how to set the GPIO names in the device tree:
 - Decompile the .dtbo in the .dts format with dtc:
cnc@raspberrypi:~$ dtc /boot/broadcom/overlays/mcp23017.dtbo -o mcp23017.dts
 - Edit the .dts file:
cnc@raspberrypi:~$ nano mcp23017.dts
    - change the I2C address if necessary (the adafruit board has the address 0x20):
mcp23017_pins@20
mcp@20
reg = <0x20>;
    - add the GPIO names in the mcp@20 section (ypu can choose your own names):
gpio-line-names = "MCP20_A0","MCP20_A1","MCP20_A2","MCP20_A3","MCP20_A4","MCP20_A5","MCP20_A6","MCP20_A7","MCP20_B0","MCP20_B1","MCP20_B2","MCP20_B3","MCP20_B4","MCP20_B5","MCP20_B6","MCP20_B7";
 - Compile the file back and save it to the firmware folder (keep a backup of the original .dtbo file)
cnc@raspberrypi:~$ dtc mcp23017.dts -o mcp23017.dtbo -O dtb
cnc@raspberrypi:~$ sudo mv /boot/broadcom/overlays/mcp23017.dtbo /boot/broadcom/overlays/mcp23017.dtbo.old
cnc@raspberrypi:~$ sudo mv mcp23017.dtbo /boot/broadcom/overlays/mcp23017.dtbo
 - reboot

After applying the patched Device Tree I got names in the gpioionfo output:
cnc@raspberrypi:~$ gpioinfo
gpiochip0 - 58 lines:
        line   0:     "ID_SDA"       unused   input  active-high
    ...
        line  57: "RGMII_TXD3"       unused   input  active-high
gpiochip1 - 8 lines:
        line   0:      "BT_ON"       unused  output  active-high
        ...
        line   7:    "SD_OC_N"       unused   input  active-high
gpiochip2 - 16 lines:
        line   0:   "MCP20_A0"       unused   input  active-high
        line   1:   "MCP20_A1"       unused   input  active-high
        line   2:   "MCP20_A2"       unused   input  active-high
        line   3:   "MCP20_A3"       unused   input  active-high
        line   4:   "MCP20_A4"       unused   input  active-high
        line   5:   "MCP20_A5"       unused   input  active-high
        line   6:   "MCP20_A6"       unused   input  active-high
        line   7:   "MCP20_A7"       unused   input  active-high
        line   8:   "MCP20_B0"       unused   input  active-high
        line   9:   "MCP20_B1"       unused   input  active-high
        line  10:   "MCP20_B2"       unused   input  active-high
        line  11:   "MCP20_B3"       unused   input  active-high
        line  12:   "MCP20_B4"       unused   input  active-high
        line  13:   "MCP20_B5"       unused   input  active-high
        line  14:   "MCP20_B6"       unused   input  active-high
        line  15:   "MCP20_B7"       unused   input  active-high

Then it is possible to use the GPIOs with the hal_gpio driver:
cnc@raspberrypi:~$ halrun
halcmd: loadrt hal_gpio inputs=MCP20_A0,MCP20_A1 outputs=MCP20_B0,MCP20_B1

halcmd: show pin
Component Pins:
Owner   Type  Dir         Value  Name
     4  bit   OUT         FALSE  hal_gpio.MCP20_A0-in
     4  bit   OUT         FALSE  hal_gpio.MCP20_A0-in-not
     4  bit   OUT         FALSE  hal_gpio.MCP20_A1-in
     4  bit   OUT         FALSE  hal_gpio.MCP20_A1-in-not
     4  bit   IN          FALSE  hal_gpio.MCP20_B0-out
     4  bit   IN          FALSE  hal_gpio.MCP20_B1-out
     4  s32   OUT             0  hal_gpio.read.time
     4  s32   OUT             0  hal_gpio.write.time
Last edit: 28 Dec 2023 21:18 by jst. Reason: Fixed the code tags again
The following user(s) said Thank You: cornholio

Please Log in or Create an account to join the conversation.

More
28 Dec 2023 19:54 #289278 by cornholio

Please Log in or Create an account to join the conversation.

Time to create page: 0.051 seconds
Powered by Kunena Forum