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

More
2 years 10 months ago #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.
Code:
cnc@raspberrypi:~$ sudo nano /boot/broadcom/config.txt
 - add follwing at the end of the file:
Code:
dtoverlay=mcp23017
 - also enable I2C if not alredy enabled:
Code:
dtparam=i2c_arm=on

After running gpioinfo the GPIO extender with the pins was shown, but they didn't have a name ('unnamed').
Code:
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:
Code:
cnc@raspberrypi:~$ dtc /boot/broadcom/overlays/mcp23017.dtbo -o mcp23017.dts
 - Edit the .dts file:
Code:
cnc@raspberrypi:~$ nano mcp23017.dts
    - change the I2C address if necessary (the adafruit board has the address 0x20):
Code:
mcp23017_pins@20 mcp@20 reg = <0x20>;
    - add the GPIO names in the mcp@20 section (ypu can choose your own names):
Code:
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)
Code:
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:
Code:
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:
Code:
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

Please Log in to join the conversation.

More
Time to create page: 0.081 seconds
Powered by Kunena Forum