MikeDK
Posts: 86
Joined: Thu Mar 19, 2015 12:01 pm

devicetree overlay for MCP23017 GPIO expander

Thu Mar 19, 2015 12:48 pm

Hi there!

For a small project of mine, I was planning to use an MCP23017 I2C GPIO Expander because I need many I/Os and I didn't want to occupy all GPIOs of the Pi.
First I wanted to write some C++ userspace code which uses i2c-dev and wrap a class around it.
But then I recently discovered the possibility to use device-tree on the Pi, and found that there is already a kernel driver gpio-mcp23s08 existing which is capable of providing /sys/class/gpio style GPIOs with the MCP23S08 (SPI), MCP23S17 (SPI), MCP23008 (I2C) and MCP23017 (I2C) chips.
I thought: "Hey, would be a cool thing, if I could use the external I/Os exactly the same way as I can use the Pi's GPIOs".
So I started to search if there is already some overlay existing for these chips.

I found none, so I wrote my own :D

Currently it only supports the MCP23017, as it is the only one I have available here to test it.
But I plan to extend it to include support for all 4 ICs which are supported by the driver.

As soon as I have finished testing (input/output work since today, but I need to verify the IRQ capability by writing some test code), I would like to share it with the community.

But first I have some questions:
  • My goal is that this overlay will some day be part of the official rpi overlays. What kind of release process is used for that purpose? Who will review this, and who decides when it can be added?
  • One problem is that the required gpio-mcp23s08 driver is not included in the raspbian (and probably all other distro) kernel packages. I had to make a custom kernel on my own ... so, again: what is the process to get this into the official kernel builds?
  • Because I don't own the other 3 ICs, I would like to invite owners of one (or more) of the following to get in contact with me, so we can test them...: MCP23008, MCP23S08 and MCP23S17
I would also like to include my currently working .dts and .dtb files, so anyone who owns an MCP23017 can try it on his own.
Please note that a custom kernel is needed for this. Maybe I can upload this somewhere too, if needed ;)
mcp23017-overlay.tar.bz2
(901 Bytes) Downloaded 1063 times
Stay cool and regards,
MikeDK

plugwash
Forum Moderator
Forum Moderator
Posts: 3845
Joined: Wed Dec 28, 2011 11:45 pm

Re: devicetree overlay for MCP23017 GPIO expander

Thu Mar 19, 2015 1:01 pm

I can't say i'm a fan of the sysfs GPIO interface. It doesn't let you set the value of a pin before making it an output and it only lets you deal with one pin at a time which makes it even slower than it needs to be (going through the kernel will always be a slow way of doing GPIO but having to do it one bit at a time multiplies the overhead), I would expect performance to be even worse in the case of an IO expander.

My feeling is you will be much better of with your original approach.

MikeDK
Posts: 86
Joined: Thu Mar 19, 2015 12:01 pm

Re: devicetree overlay for MCP23017 GPIO expander

Thu Mar 19, 2015 1:35 pm

plugwash wrote:I can't say i'm a fan of the sysfs GPIO interface. It doesn't let you set the value of a pin before making it an output and it only lets you deal with one pin at a time which makes it even slower than it needs to be (going through the kernel will always be a slow way of doing GPIO but having to do it one bit at a time multiplies the overhead), I would expect performance to be even worse in the case of an IO expander.

My feeling is you will be much better of with your original approach.
You may be right about the performance issue. But fortunately in my project, the gpios are only needed to do some relay switching and for monitoring some switches ... so no speed needed ;)

I am just thinking: If there is already a kernel driver available for a device, why not use it?
Why should I put effort into writing a neat C++ class which drives my MCP23017, when there is already a slim kernel driver, which does the same thing in a more efficient way? Because If I would do the I2C communication via the i2c-dev interface, there would also be much performance loss in the userspace-kernel switching ...

One thing should be clear: An I2C GPIO expander is not good for doing some high frequency bit-banging stuff ... but for slower switching and monitoring purposes it is a nice thing when you don't want to use the Pi's own GPIOs


regards,
MikeDK

MikeDK
Posts: 86
Joined: Thu Mar 19, 2015 12:01 pm

Re: devicetree overlay for MCP23017 GPIO expander

Thu Mar 19, 2015 8:04 pm

Okay, I did some IRQ testing now, and ran into a problem.

Normal Input/Output is no problem. But as soon as I enable the interrupt on a GPIO the trouble begins...

I do following:

Code: Select all

echo "496" > /sys/class/gpio/export
echo "both" > /sys/class/gpio/gpio496/edge
Now when I change the state of the gpio pin on the MCP23017, after 2-3 seconds I get a system message "IRQ #389 happened and nobody cared".

A google search told me that this happens, when an IRQ is happening more than 100.000 times being not handled.
More precisely, when the interrupt handler function of the driver does not return IRQ_HANDLED.

When I look at the driver source, I can see the handler function:

Code: Select all

static irqreturn_t mcp23s08_irq(int irq, void *data)
{
        struct mcp23s08 *mcp = data;
        int intcap, intf, i;
        unsigned int child_irq;

        mutex_lock(&mcp->lock);
        intf = mcp->ops->read(mcp, MCP_INTF);
        if (intf < 0) {
                mutex_unlock(&mcp->lock);
                return IRQ_HANDLED;
        }

        mcp->cache[MCP_INTF] = intf;

        intcap = mcp->ops->read(mcp, MCP_INTCAP);
        if (intcap < 0) {
                mutex_unlock(&mcp->lock);
                return IRQ_HANDLED;
        }

        mcp->cache[MCP_INTCAP] = intcap;
        mutex_unlock(&mcp->lock);


        for (i = 0; i < mcp->chip.ngpio; i++) {
                if ((BIT(i) & mcp->cache[MCP_INTF]) &&
                    ((BIT(i) & intcap & mcp->irq_rise) ||
                     (mcp->irq_fall & ~intcap & BIT(i)))) {
                        child_irq = irq_find_mapping(mcp->irq_domain, i);
                        handle_nested_irq(child_irq);
                }
        }

        return IRQ_HANDLED;
}
There is simply no way that this function, once called, will return some other value than IRQ_HANDLED.
This means that it won't get called at all :|

I'm not really sure why ... I don't think it's a problem of the driver, because it is in the kernel for a long time now (at least since 2.6) ... my guess is that I have done something wrong in the devicetree overlay.
When I wrote it, I took hy28a-overlay.dts as example because there is also an interrupt pin defined for the ads7846 touchscreen part ... maybe I am misinterpreting something :roll:

Any suggestions?

regards,
MikeDK

notro
Posts: 755
Joined: Tue Oct 16, 2012 6:21 pm
Location: Drammen, Norway

Re: devicetree overlay for MCP23017 GPIO expander

Thu Mar 19, 2015 9:32 pm

It doesn't let you set the value of a pin before making it an output
Actually you can. It was previously broken in the new gpio driver, but is fixed in the latest rpi-update kernels.
From https://www.kernel.org/doc/Documentation/gpio/sysfs.txt

Code: Select all

    /sys/class/gpio/gpioN/

	"direction" ... reads as either "in" or "out". This value may
		normally be written. Writing as "out" defaults to
		initializing the value as low. To ensure glitch free
		operation, values "low" and "high" may be written to
		configure the GPIO as an output with that initial value.
Source: http://lxr.free-electrons.com/ident?i=g ... tion_store
Now when I change the state of the gpio pin on the MCP23017, after 2-3 seconds I get a system message "IRQ #389 happened and nobody cared".
Check /proc/interrupts to see who 389 is.
Add printk's to the irq routine to detect the code path.

MikeDK
Posts: 86
Joined: Thu Mar 19, 2015 12:01 pm

Re: devicetree overlay for MCP23017 GPIO expander

Thu Mar 19, 2015 9:40 pm

notro wrote:Check /proc/interrupts to see who 389 is.
Add printk's to the irq routine to detect the code path.
Thanks for the hint!
Will test this tomorrow, as my project lies on my desk in the office :)

MikeDK
Posts: 86
Joined: Thu Mar 19, 2015 12:01 pm

Re: devicetree overlay for MCP23017 GPIO expander

Fri Mar 20, 2015 7:03 am

Ok got some new information ... the interrupt # 398 which causes the troubles is registered to the bcm2835:

Code: Select all

root@berry:/# cat /proc/interrupts 
           CPU0       
  3:      63797   ARMCTRL   3  BCM2708 Timer Tick
 16:          0   ARMCTRL  16  bcm2708_fb dma
 24:        299   ARMCTRL  24  DMA IRQ
 25:       3274   ARMCTRL  25  DMA IRQ
 32:     713306   ARMCTRL  32  dwc_otg, dwc_otg_pcd, dwc_otg_hcd:usb1
 49:     100001   ARMCTRL  49  20200000.gpio:bank0
 50:          0   ARMCTRL  50  20200000.gpio:bank1
 65:         12   ARMCTRL  65  ARM Mailbox IRQ
 66:          2   ARMCTRL  66  VCHIQ doorbell
 75:          1   ARMCTRL  75
 79:         54   ARMCTRL  79  20804000.i2c
 84:      13892   ARMCTRL  84  mmc0
398:     100001  pinctrl-bcm2835   4  1-0020
456:          1  gpio-mcp23xxx   8  gpiolib
FIQ:              usb_fiq
Err:          0
We can see here that it got triggered 100001 times ... this is the same amount as the IRQ 49 (gpio:bank0).

So because it didn't complain about IRQ 49 it means that the irqhandler function of the bcm2835 handled the interrupts correctly ... it looks like the bcm2835 does not call the irqhandler function of the gpio-mcp23s08 driver.

Is it possible that I need to define something in the devicetree overlay which tells the kernel how an interrupt on a rpi gpio has to be routed to a driver which needs it?
I mean I defined "interrupt-controller" in the mcp part of the overlay, which seemed correct for me, as I want it to receive interrupts... but in the second thought this does not seem enough.

Has anyone ever done this with success?
I mean using an external IC which is both interrupt source and interrupt controller?

fyi i also add the sys message with the stackdump...:

Code: Select all

[ 1751.145352] irq 398: nobody cared (try booting with the "irqpoll" option)
[ 1751.152340] CPU: 0 PID: 0 Comm: swapper Not tainted 3.18.9+ #1
[ 1751.158354] [<c0014ebc>] (unwind_backtrace) from [<c0012630>] (show_stack+0x20/0x24)
[ 1751.166288] [<c0012630>] (show_stack) from [<c0545ca0>] (dump_stack+0x20/0x28)
[ 1751.173690] [<c0545ca0>] (dump_stack) from [<c005f554>] (__report_bad_irq.isra.7+0x30/0x13c)
[ 1751.182318] [<c005f554>] (__report_bad_irq.isra.7) from [<c005f92c>] (note_interrupt+0x254/0x2b4)
[ 1751.191384] [<c005f92c>] (note_interrupt) from [<c005d31c>] (handle_irq_event_percpu+0xc0/0x260)
[ 1751.200352] [<c005d31c>] (handle_irq_event_percpu) from [<c005d530>] (handle_irq_event+0x74/0x90)
[ 1751.209413] [<c005d530>] (handle_irq_event) from [<c005ff6c>] (handle_simple_irq+0x88/0xdc)
[ 1751.217937] [<c005ff6c>] (handle_simple_irq) from [<c005c904>] (generic_handle_irq+0x34/0x4c)
[ 1751.226647] [<c005c904>] (generic_handle_irq) from [<c030f050>] (bcm2835_gpio_irq_handle_bank+0xc4/0x124)
[ 1751.236408] [<c030f050>] (bcm2835_gpio_irq_handle_bank) from [<c030f0fc>] (bcm2835_gpio_irq_handler+0x4c/0xac)
[ 1751.246610] [<c030f0fc>] (bcm2835_gpio_irq_handler) from [<c005d29c>] (handle_irq_event_percpu+0x40/0x260)
[ 1751.276571] [<c005d29c>] (handle_irq_event_percpu) from [<c005d530>] (handle_irq_event+0x74/0x90)
[ 1751.306632] [<c005d530>] (handle_irq_event) from [<c0060408>] (handle_level_irq+0xa8/0x160)
[ 1751.336356] [<c0060408>] (handle_level_irq) from [<c005cb8c>] (__handle_domain_irq+0x7c/0xd0)
[ 1751.366540] [<c005cb8c>] (__handle_domain_irq) from [<c000852c>] (asm_do_IRQ+0x2c/0x30)
[ 1751.396348] [<c000852c>] (asm_do_IRQ) from [<c054ad18>] (__irq_svc+0x38/0xd0)
[ 1751.414542] Exception stack(0xc07e9e38 to 0xc07e9e80)
[ 1751.430703] 9e20:                                                       00000000 c083fac0
[ 1751.460319] 9e40: 00000001 c07f0f48 c07e8000 c0026470 00000000 00000002 00000000 c0839d26
[ 1751.489390] 9e60: c0839d26 c07e9ecc c07e9e80 c07e9e80 c0025e6c c0025e70 60000113 ffffffff
[ 1751.518492] [<c054ad18>] (__irq_svc) from [<c0025e70>] (__do_softirq+0xc4/0x36c)
[ 1751.546768] [<c0025e70>] (__do_softirq) from [<c0026470>] (irq_exit+0xbc/0x110)
[ 1751.564657] [<c0026470>] (irq_exit) from [<c005cb94>] (__handle_domain_irq+0x84/0xd0)
[ 1751.593316] [<c005cb94>] (__handle_domain_irq) from [<c000852c>] (asm_do_IRQ+0x2c/0x30)
[ 1751.622018] [<c000852c>] (asm_do_IRQ) from [<c054ad18>] (__irq_svc+0x38/0xd0)
[ 1751.639521] Exception stack(0xc07e9f20 to 0xc07e9f68)
[ 1751.654850] 9f20: 00000000 00000000 00000000 c07f0f48 00000002 c07e8000 00000000 c07f008c
[ 1751.683521] 9f40: c083a788 c0839d26 c0839d26 c07e9f74 c07e9f68 c07e9f68 c000f304 c000f308
[ 1751.712017] 9f60: 60000013 ffffffff
[ 1751.725505] [<c054ad18>] (__irq_svc) from [<c000f308>] (arch_cpu_idle+0x30/0x40)
[ 1751.752740] [<c000f308>] (arch_cpu_idle) from [<c004f928>] (cpu_startup_entry+0x1a4/0x210)
[ 1751.780811] [<c004f928>] (cpu_startup_entry) from [<c0541600>] (rest_init+0x80/0x98)
[ 1751.808625] [<c0541600>] (rest_init) from [<c0793ca8>] (start_kernel+0x364/0x3cc)
[ 1751.836849] handlers:
[ 1751.849239] [<c005d54c>] irq_default_primary_handler threaded [<bf010998>] mcp23s08_irq [gpio_mcp23s08]
[ 1751.878872] Disabling IRQ #398
[ 1751.892143] sched: RT throttling activated

regards,
MikeDK

notro
Posts: 755
Joined: Tue Oct 16, 2012 6:21 pm
Location: Drammen, Norway

Re: devicetree overlay for MCP23017 GPIO expander

Fri Mar 20, 2015 6:21 pm

Code: Select all

398:     100001  pinctrl-bcm2835   4  1-0020
456:          1  gpio-mcp23xxx   8  gpiolib
I assume this means:
pinctrl-bcm2835 pin 4 is used by device 1-0020
gpio-mcp23xxx pin 8 is used by gpiolib (http://lxr.free-electrons.com/ident?i=gpio_sysfs_irq)

There is one interrupt registered. Have you added printk to mcp23s08_irq() to see if it is called?
And you are polling the gpio value file?

Your overlay looks fine, it doesn't appear to be anything missing: https://www.kernel.org/doc/Documentatio ... p23s08.txt

MikeDK
Posts: 86
Joined: Thu Mar 19, 2015 12:01 pm

Re: devicetree overlay for MCP23017 GPIO expander

Fri Mar 20, 2015 10:58 pm

I assume this means:
pinctrl-bcm2835 pin 4 is used by device 1-0020
gpio-mcp23xxx pin 8 is used by gpiolib (http://lxr.free-electrons.com/ident?i=gpio_sysfs_irq)
yes that seems reasonable ... device 1-0020 sounds like i2c-1 address 0x20, which is my configuration
and pin8 of gpio-mcp23xxx is exactly the pin I triggered for testing
There is one interrupt registered. Have you added printk to mcp23s08_irq() to see if it is called?
And you are polling the gpio value file?
yep, did that today ... it gets called exactly one time.
I also added some other printk's to see what's going on in the driver and how it gets setup ... everything goes like expected

I was planning to use the poll() function, yes ... but the error occurs without any program accessing the gpio ... i simply switch the line, and 1 second later 100000 irqs were not, and 1 was handled by the driver :?

I don't think that should happen only because I am not poll()ing it ... it should be ok to enable the interrupt on a gpio without immediately using it
Your overlay looks fine, it doesn't appear to be anything missing: https://www.kernel.org/doc/Documentatio ... p23s08.txt
that brings me to the thing I found out today:

I was wondering why in the driver's function mcp23s08_irq_setup() the irq gets requested with IRQF_TRIGGER_LOW ... I changed that to IRQF_TRIGGER_FALLING, and now it comes: it worked like a charm ... exactly how I wanted it :P

Then I realized that I changed one thing in the overlay from the gpio-mcp23s08.txt example: the line with the interrupt specifier should be

Code: Select all

interrupts = <4 8>;
because IRQ_TYPE_LEVEL_LOW from the example has the value 8

I used value 2 (IRQ_TYPE_EDGE_FALLING) because I thought that would be better.

Now I tried level_low from the example and reverted the change in the driver and: still not working :|

I am not sure now how to interpret this ... there are several guys working on that driver, and one of them was writing in his commit comment that he tested the i2c chip with interrupt on an arm platform, and it worked ...

why is it not working here? (or was the guy lying? :D )

I don't know ... :/


regards,
MikeDK

MikeDK
Posts: 86
Joined: Thu Mar 19, 2015 12:01 pm

Re: devicetree overlay for MCP23017 GPIO expander

Fri Mar 27, 2015 9:38 am

Hi!

I finally managed to get rid of the irq problem, but only with a small patch of the kernel driver.
For those interested, I will post it here:

Code: Select all

diff -rupN a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c
--- a/drivers/gpio/gpio-mcp23s08.c      2015-03-27 10:26:30.177364200 +0100
+++ b/drivers/gpio/gpio-mcp23s08.c      2015-03-27 10:30:41.724249813 +0100
@@ -485,7 +485,7 @@ static int mcp23s08_irq_setup(struct mcp
                return -ENODEV;
 
        err = devm_request_threaded_irq(chip->dev, mcp->irq, NULL, mcp23s08_irq,
-                                       IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+                                       IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
                                        dev_name(chip->dev), mcp);
        if (err != 0) {
                dev_err(chip->dev, "unable to request IRQ#%d: %d\n",
This changes the registration of the gpio-mcp23s08 irq handler funtion to be called edge-triggered instead of level triggered ... I still do not know why, but with level triggering it is not working for me.

I already posted a question to the gpio kernel mailing list, but no one answered yet ... maybe I will write a patch to make the triggering configurable via devicetree, we'll see ...


regards,
MikeDK

notro
Posts: 755
Joined: Tue Oct 16, 2012 6:21 pm
Location: Drammen, Norway

Re: devicetree overlay for MCP23017 GPIO expander

Wed Apr 08, 2015 3:11 pm

This might be the source of your problem:
[PATCH] pinctrl: bcm2835: Fix support for threaded level triggered IRQs
https://lkml.org/lkml/2015/4/7/194

MikeDK
Posts: 86
Joined: Thu Mar 19, 2015 12:01 pm

Re: devicetree overlay for MCP23017 GPIO expander

Mon Apr 13, 2015 1:05 pm

notro wrote:This might be the source of your problem:
[PATCH] pinctrl: bcm2835: Fix support for threaded level triggered IRQs
https://lkml.org/lkml/2015/4/7/194
nice!
I will try this patch this week and post the results.

Thanks!

jabss
Posts: 69
Joined: Thu May 09, 2013 11:47 am

Re: devicetree overlay for MCP23017 GPIO expander

Fri Jul 03, 2015 10:58 pm

Hi,

Very interesting thread. I tried to understand it all, but I guess my knowledge about coding is rather limited.

I have always used the GPIO /sys/class/gpio style for PCF857x's although I had the feeling I was one of the very few:
viewtopic.php?p=545887#p545887

Anyway, I'd like to setup a set of MCP23017's and connect all the interrupt pins together into one of the RPI GPIO in order to use the interrupt functionality. (basically, when an input pin is changed in MCP23017, its INT pin gets "on" and since its connected to RPI GPIO, which has interrupt functionality, creates an interrupt on the RPI itself. Then, my code will pool all MCP's to find out which port has changed - This should be much more efficient than pooling all MCP's every second or so)

My experiences so far with the MCP23017 and the GPIO Linux driver shown that the interrupt handling does not exist, and I guess that is what is been discussed here: A way to add it to the existing driver through the means of an "overlay".

I even tried to setup the interrupts on the MCP's by sending I2Cset commands before invoking the driver, but somehow when its loaded, the MCP's loose their configuration.

In this thread, many links are shared, as well as some patches. However, I'm afraid I don't know to evaluate what is the best solution for my problem, so I'd like to ask what is the best patch to apply (I have the latest kernel) and how could I do it.

Anyone could point me towards the right direction?

Thanks!
Jabss

miltmobley
Posts: 11
Joined: Mon Jun 29, 2015 9:14 pm

Re: devicetree overlay for MCP23017 GPIO expander

Tue Jul 07, 2015 3:39 am

I noticed a difference between your dts overlay and the mcp driver file:
your dts has: "microchip,mcp23017"
while the driver file has: "microchip,mcp23s17" for the of match entry
These should match to ensure the mcp driver is loaded.

Since you specified 'status = "okay"' in the dts, the kernel should have tried to match the dts node to a driver,
and may have succeeded in matching "microchip" instead of "mcp23s17". Did you use lsmod to
verify the driver was loaded?

I reviewed the bcm pinctrl driver and the pcm driver. The pinctrl driver clears its own interrupt request line,
and then calls "generic_handle_irq", a kernel function that looks up the interrupt in a tree of interrupt descriptors.
I suspect the pcm probe function is also registering its interrupt in this tree. So if you could get the pinctrl driver to pass
the pcm interrupt number instead of its own, it might work. But this would require a custom kernel.

The patch to fix the pinctrl driver that was mentioned by the other poster is in the 4.0.7 kernel.

User avatar
joan
Posts: 16281
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: devicetree overlay for MCP23017 GPIO expander

Tue Jul 07, 2015 7:38 am

By the way, the MCP23017 is an I2C chip and uses the I2C bus. The MCP23S17 is a SPI chip and uses the SPI bus.

miltmobley
Posts: 11
Joined: Mon Jun 29, 2015 9:14 pm

Re: devicetree overlay for MCP23017 GPIO expander

Tue Jul 07, 2015 6:24 pm

Joan is right, I was looking at the SPI section of the mcp driver.

But on the main subject, the problem I see is that the gpio interrupt signal is being handled by the bcm2835-pinctrl driver,
which does not know that the mcp driver is supposed to handle it. You need to have some way to tell it to do so.
I found a fairly large number of example drivers that use the "irq_set_chained_handler" function to do this,
but there is no documentation to explain how to use it. The example irq-brcmstb-l2.c, which is a Broadcom set top box
component, may be helpful.

miltmobley
Posts: 11
Joined: Mon Jun 29, 2015 9:14 pm

Re: devicetree overlay for MCP23017 GPIO expander

Wed Jul 08, 2015 2:43 am

Hi I found some info that may provide an approach to solve your problem:

In the kernel source, look at Documentation/gpio/driver.txt, in the section titled "NESTED THREADED GPIO irqchips".
The text appears to describe what you are trying to achieve, and gives some fragments of sample code that
mention the device "tc3589x". In the arm/boot/dts files I found this referred to in e.g. ste-hrefprev60.dtsi,
where a sub node of an i2c node is declared as :
compatible = "toshiba,tc35892";
and
interrupt-parent = <&gpio6>;

Curiously, tx3589x turns out to be gpio expander chips from Toshiba. Possibly you could use one of those chips and just copy
their code. At any rate you should be able to use it for a design model.

MikeDK
Posts: 86
Joined: Thu Mar 19, 2015 12:01 pm

Re: devicetree overlay for MCP23017 GPIO expander

Sun Feb 21, 2016 6:27 pm

Hi all, long time no see ;)

The last year I had no time to investigate further into my problem, as my family and me were moving into a house, and that was kinda work enough ...

Today, I checked my hardware again, and did an rpi-update to get the newest kernel, and surprise: not only the gpio_mcp23s08 kernel driver is now available without compiling it by myself - also my overlay is now working perfectly with interrupt capability on each mcp23017 pin :D

I guess the patch in the pinctrl driver which was mentioned by notro has fixed the issue.

In the next few days I will update the overlay to enable users to parametrize the irq pin and the mcp i2c address, so users can use up to 8 mcp23017 devices.


regards,
Mike

oscargomezf
Posts: 27
Joined: Thu Mar 10, 2016 3:46 pm
Location: Santander, ES

Re: devicetree overlay for MCP23017 GPIO expander

Fri Apr 29, 2016 7:36 am

Hi Mike,

Right know I'm working on something similar to your project. I would like to add the SMBus IO Expander TCA6424A, and I need to build a .dts overlay for this purpose.

Could you upload the final .dts? I would like to check it.

Best regards.
Oscar Gomez Fuente

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 15893
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: devicetree overlay for MCP23017 GPIO expander

Fri Apr 29, 2016 10:25 am

@MikeDK: Yes, please create a pull request with your overlay on https://github.com/raspberrypi/linux (you've probably found that they live under arch/arm/boot/dts/overlays)
I was about to sit down and investigate this when this thread got pinged, so it'd save us all some effort.
Software Engineer at Raspberry Pi Ltd. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

masv
Posts: 2
Joined: Tue May 17, 2016 6:00 pm

Re: devicetree overlay for MCP23017 GPIO expander

Wed May 18, 2016 3:59 pm

@MikeDK

I have been trying to use your overlay file by adding the following to the /boot/config.txt file:

dtoverlay=mcp23017

and copying it into /boot/overlays

I do not get any errors in the message file during a boot to indicate that there is something wrong fith the overlay file

I have tried to recompile your dts file, and do a diff towards yours dtb file without any diff, and I have tried to name it
mcp23017.dtbo

But without any success, what am I missing ??

My mcp23017 is showing up on address 0x20, but to which gpio's do I need to connect its INTR pins

Thanks in advance
Martin

wavelet
Posts: 17
Joined: Mon Mar 21, 2016 7:15 pm

Re: devicetree overlay for MCP23017 GPIO expander

Sun May 22, 2016 8:15 pm

MikeDK wrote:Currently it only supports the MCP23017, as it is the only one I have available here to test it.
But I plan to extend it to include support for all 4 ICs which are supported by the driver.
Have you made any progress with the other variants? I'm trying to get a MCP23S17 going and have written the following device tree but the chip is not appearing in /sys/class/gpio:

Code: Select all

// Definitions for MCP23S17 Gpio Extender from Microchip Semiconductor

// Example for single device wired to use address 0, CS#0 and no interrupts.

/dts-v1/;
/plugin/;

/ {
	compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709";

	fragment@0 {
		target = <&spi0>;
		__overlay__ {
			status = "okay";
		};
	};

	// disable spi-dev for spi0.0
	fragment@1 {
		target = <&spidev0>;
		__overlay__ {
			status = "disabled";
		};
	};

	// enable mcp23s17 for spi0.0
	fragment@2 {
		target = <&spi0>;
		__overlay__ {
			#address-cells = <1>;
			#size-cells = <0>;
			mcp23s17@0 {
				compatible = "microchip,mcp23s17";
  				gpio-controller;
  				#gpio-cells = <2>;
    				spi-present-mask = <0x01>;
     				reg = <0>;
    				spi-max-frequency = <1000000>;

				status = "okay";
			};
		};
	};
};
Can you tell me how you pass the platform data (like which range of GPIOs the device should map to and whether or not pullups are enabled on input ports) to the driver when you use the device tree? When you ran the commands

Code: Select all

    echo "496" > /sys/class/gpio/export
    echo "both" > /sys/class/gpio/gpio496/edge
why was your MCP23017 mapped to gpio496?

MikeDK
Posts: 86
Joined: Thu Mar 19, 2015 12:01 pm

Re: devicetree overlay for MCP23017 GPIO expander

Mon May 23, 2016 1:07 pm

6by9 wrote:@MikeDK: Yes, please create a pull request with your overlay on https://github.com/raspberrypi/linux (you've probably found that they live under arch/arm/boot/dts/overlays)
I was about to sit down and investigate this when this thread got pinged, so it'd save us all some effort.
I just created a pull request for adding this overlay ;)

regards,
MikeDK

MikeDK
Posts: 86
Joined: Thu Mar 19, 2015 12:01 pm

Re: devicetree overlay for MCP23017 GPIO expander

Mon May 23, 2016 1:12 pm

masv wrote:@MikeDK

I have been trying to use your overlay file by adding the following to the /boot/config.txt file:

dtoverlay=mcp23017

and copying it into /boot/overlays

I do not get any errors in the message file during a boot to indicate that there is something wrong fith the overlay file

I have tried to recompile your dts file, and do a diff towards yours dtb file without any diff, and I have tried to name it
mcp23017.dtbo

But without any success, what am I missing ??

My mcp23017 is showing up on address 0x20, but to which gpio's do I need to connect its INTR pins

Thanks in advance
Martin
Hi masv,

please try my updated version which can be found here:

https://github.com/MikeDK/linux/commit/ ... 9f1074da2b

With this new version, you can set the gpio pin, which is connected to the INTA pin of the MCP23017, via the "gpiopin" parameter.
Old version needed to be connected to gpio pin 4.

regards,
MikeDK
Last edited by MikeDK on Tue May 24, 2016 8:33 am, edited 1 time in total.

wavelet
Posts: 17
Joined: Mon Mar 21, 2016 7:15 pm

Re: devicetree overlay for MCP23017 GPIO expander

Tue May 24, 2016 8:16 am

wavelet wrote:...why was your MCP23017 mapped to gpio496?
Don't worry, I've figured it out. In my overlay, I need to change the property "spi-present-mask" to "microchip,spi-present-mask". (The example code at the end of the devicetree bindings documentation file gpio-mcp23s08.txt has the same error.) With this fix, the device driver loads successfully and the OS automatically assigns its GPIOs to gpio496 thru gpio511, i.e. it assigns new devices to GPIOs from 511 downwards.
At some point I might have a go at rewriting my overlay so that you can define a device's SPI bus number, SPI address and CS number using dtparam.

Return to “Advanced users”