4

I'm trying to add a PCA9557 I/O expander to an arm-based system on an I2C bus. The system already has another I/O expander on a different I2C bus. I am trying to figure out how to specify which GPIO numbers the pins on the new expander get, and how to get both working.

Here's the device tree section for the existing expander, under I2C bus 2:

        i2c2: i2c@e8007000 {
        status = "ok";

        pca9539: pca9539@74 {
            compatible = "nxp,pca9539";
            reg = <0x74>;
            interrupt-parent = <&gpio>;
            interrupts = <9 0x0>;
            gpio-controller;
            #gpio-cells = <2>;
            interrupt-controller;
            #interrupt-cells = <2>;
        };
        };

Using the above, the existing I/O expander (with 16 GPIOs) appears in linux as /sys/class/gpio/gpiochip128, exposing GPIO numbers 128 - 143. GPIOs 0-127 are built in to the host processor.

I added the following for the new expander on I2C bus 0:

   i2c0: i2c@e8003000 {
        status = "ok";

        pca9557: pca9557@18 {
            compatible = "nxp,pca9557";
            reg = <0x18>;
            gpio-controller;
            #gpio-cells = <2>;
        };

I also modified the kernel config to build the GPIO_PCA953X driver, which should support the PCA9557.

When I compile and boot with the above added to the device tree, I now see the NEW expander (PCA9557) mapped as /sys/class/gpio/gpiochip136, and it works (I can set its IO 0 pin using GPIO128).

However, there are no longer any GPIO pins for the other expander. It still appears as a device on the appropriate bus under /sys/devices/... but a directory listing doesn't show the "driver..." and "i2c-2" items which were there before.

So how do I get BOTH expanders to appear in /sys/class/gpio/ with different ranges of GPIO numbers, so I can use both?

I guess the "128" as the base GPIO for the original expander was just the next available GPIO? But why does the new expander end up starting at GPIO 136?

I've seen several references to this page: GPIO bindings documentation, but it was fairly generic and didn't help much.

Jeremy
  • 1,083
  • 3
  • 13
  • 25
  • Just a guess: What happens if you reverse the definition order in the file? Does the problem track? I note that your new definition is at a lower address than the previous one. Should that come first or does it make no difference? Lastly, the old definition has some fields that aren't in the new one (e.g. `interrupt-parent`). Is that a factor? Also, the link you gave is to online version of kernel's `Documentation` dir [which is in kernel source you have]. I checked, there are other relevant files nearby [cited on your linked page]. – Craig Estey Nov 25 '15 at 06:27
  • 1
    Hmm, I didn't actually add the I2C bus nodes shown above - just the node for "pca9557: {...}". They are on different I2C busses, hence the different addresses. I don't think the order matters in this context; in fact the node for I2C0 does come before I2C2 in the dts file. There are various other devices in each I2C bus node. The pca9539 chip supports interrupts whereas the pca9557 doesn't, hence why there are interrupt details for the pca9539. I've seen hints that there GPIO numbering may have something to do with a 'pinctl" section but can't find examples or details... – Jeremy Nov 26 '15 at 00:57
  • 1
    See dir Documentation/devicetree/bindings/pinctrl and pinctrl-bindings.txt I had that up in a window since yesterday. May not be the whole deal but worth a read, IMO – Craig Estey Nov 26 '15 at 04:26
  • As Craig said, I suspect that your new node is stomping on the previously allocated pin controls. This is an old question, but please post the pinctrl definitions. – Xofo Nov 03 '16 at 21:51
  • Apologies to anyone who is interested in this question; unfortunately it was a while ago and I am no longer working on that project. Unfortunately I don't recall how it was resolved (if at all!). It probably had something to do with pinctrl definitions. – Jeremy Nov 23 '17 at 18:44

0 Answers0