__David__
Posts: 5
Joined: Fri Dec 08, 2017 11:58 am

using mcp23s17 device tree with gpio-leds

Fri Dec 08, 2017 12:24 pm

Hello, I am trying to use gpio-leds connected to MCP23s17. I will use overlays for my configurations. I combined this overlay, but it only works with gpios on board. When I try to write gpios = <& gpio 507 0>; It does not work
P.S. 507 is mcp23s17 which I get from "/ sys / class / gpio / gpiochip496"
Please tell me what I'm doing wrong
how can I use mcp23s17 gpio's in Overlay.
Thanks a lot.

Code: Select all

/*
 * Device Tree overlay for Ledcontrol
 *
 */

/dts-v1/;
/plugin/;

/ {

        compatible = "brcm,bcm2708","microchip,mcp23s08";

        [email protected] {
                target = <&leds>;
                __overlay__ {
                        compatible = "gpio-leds";
                        led_red: led_red {
                                labele = "red_led";
                                linux,default-trigger = "default-on";
                                gpios = <&gpio 5 0>;
                        };
                };
        };
        __overrides__ {
                led_gpio_red =  <&led_red>,"gpios:4";
                led_trigger =   <&led_red>,"linux,default-trigger";
        };

};

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 2589
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: using mcp23s17 device tree with gpio-leds

Fri Dec 08, 2017 9:47 pm

There are (at least) two levels of GPIO naming in Linux. Each GPIO controller provides a number of GPIOs, and the kernel can uniquely refer to any of them using a (controller, gpio index) pair. The kernel takes all the GPIOs from all controllers and assembles them into a flat list, giving each a unique number. It is those numbers that are used by the /sys/class/gpio userspace interface, but Device Tree uses the kernel method.

In Device Tree, the controller is selected using a reference to a label (normally "&gpio" for the BCM2835 GPIO controller). The standard controller uses an extra value to hold a flag indicating whether the polarity is active high (0) or active low (1) - this is backwards, but think of it as 0=normal and 1=inverted.

The mcp23s17 is a device on an SPI bus, but it is also a GPIO controller, and the Device Tree declaration must say so. This is already taken care of by the mcp23s17 overlay. Before I give you a link I should explain that the overlay parameter mechanism is quite limited, so to overcome these limitations the overlay includes all possible variants of controller, bus and chip enable, just activating the required one. Fortunately only the selected parts of the overlay end up in the final DT, otherwise it would get rather crowded.

I'm going to assume that you have an mcp23s017 on spi0.0, which corresponds to fragment 16 of the mcp23s17 overlay. You need to copy this into your overlay, changing the "__dormant__" to say "__overlay__". This node has a label of "mcp23s17_00", and I'll assume you aren't changing that.

Now you've laid the groundwork, all that remains is to connect the gpio_leds instance to one of the GPIOs provided by the mcp23s17. The "bindings" document (a description of the DT interface presented by a driver) for the MCP is here. Like the standard controller it wants a flags value, even though it is unused, so your GPIO reference becomes:

Code: Select all

                                gpios = <&mcp23s17_00 11 0>;
where I've guessed that 507 was GPIO 11 of the block based at 496.

By the way - you can remove the compatible string you added at the start of the overlay - it is wrong, but it is also completely ignored.

You might be wondering why we can't use the existing mcp23s17 overlay rather than copy a bit of it. The answer is that the labels defined by the overlay are local to the overlay, and so not available for use by other overlays. It is possible to work around this, but only by modifying the overlay containing the symbol to be exported in a rather ugly way - see the i2c-gpio overlay for an example of this technique.

__David__
Posts: 5
Joined: Fri Dec 08, 2017 11:58 am

Re: using mcp23s17 device tree with gpio-leds

Mon Dec 11, 2017 9:34 am

PhilE thank you for your answer,

it was really helpful, i have connect 3 led and it works.
hier is my overlay if somebody need it.

Code: Select all

/*
 * Device Tree overlay for Ledcontrol
 *
 */

/dts-v1/;
/plugin/;

/{
        [email protected] {
                target = <&spi1>;
                __overlay__ {
                        status = "okay";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        mcp23s17_10: [email protected] {
                                compatible = "microchip,mcp23s17";
                                gpio-controller;
                                #gpio-cells = <2>;
                                microchip,spi-present-mask = <0x01>;
                                reg = <0>;
                                spi-max-frequency = <500000>;
                                status = "okay";
                        };
                };
        };

        [email protected] {
                target = <&leds>;
                __overlay__ {
                        compatible = "gpio-leds";
                        led_mcp_11: led_mcp_11 {
                                labele = "red_led";
                                linux,default-trigger = "default-on";
                                gpios = <&mcp23s17_10 11 0>;
                        };
                };
        };
        __overrides__ {
                led_trigger_11 =  <&led_mcp_11>,"linux,default-trigger";
         };
};
        
p.s. Can you please get a look on my overlay if is everything correct.
Thanks again

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 2589
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: using mcp23s17 device tree with gpio-leds

Mon Dec 11, 2017 3:35 pm

The overlay looks OK to me - it compiles, but I haven't used it - except for one thing: the "labele" property should say "label".

__David__
Posts: 5
Joined: Fri Dec 08, 2017 11:58 am

Re: using mcp23s17 device tree with gpio-leds

Mon Dec 18, 2017 8:46 am

Hallo PhilE I have try to write parameters for my LED in config.txt but for some reason I can configure just 2 parameters. In

Code: Select all

sudo vcdbg log msg
i get

Code: Select all

002392.839: Loaded overlay 'led-overlay'
002392.859: dtparam: led_trigger_0=timer
002394.429: dtparam: led_trigger_8=timer
002397.305: dtparam: led_trigger_10=ti
003789.092: Device tree loaded to 0x2effa900 (size 0x56db)
so it donnt rekognized the LED trigger 10.
my config.txt looks like:

Code: Select all

dtoverlay=led-overlay,led_trigger_0=timer,led_trigger_8=timer,led_trigger_10=timer
how can I configure more than 2 Parameters?

Thanks for your help

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 2589
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: using mcp23s17 device tree with gpio-leds

Mon Dec 18, 2017 9:22 am

Ah, you've discovered the 80 character line limit for config.txt entries. Fortunately there is a workaround.

Parameters that appear as part of the dtoverlay line are treated exactly the same as subsequent dtparam lines. The point where the overlay content is finalised and the parameters go out of scope isn't the end of the line - it's the next dtoverlay directive or the end of the file. This means you can rewrite your line like this:

Code: Select all

dtoverlay=led-overlay,led_trigger_0=timer,led_trigger_8=timer
dtparam=led_trigger_10=timer
or this:

Code: Select all

dtoverlay=led-overlay
dtparam=led_trigger_0=timer
dtparam=led_trigger_8=timer
dtparam=led_trigger_10=timer
In case you were wondering how global dtparams (like "i2c_arm=on") are distinguished from overlay parameters, the answer is that all parameters are first checked against the current overlay before checking the base Device Tree. It's better to avoid using the same parameter names in overlays as found in the base DTB, but if you do and you want to refer to the global parameter you can either put it before the clashing overlay is loaded, or after it has been unloaded (triggered by the loading of the next overlay or by an empty "dtoverlay=").

wiwi
Posts: 8
Joined: Fri Aug 02, 2019 1:35 pm

Re: using mcp23s17 device tree with gpio-leds

Tue Nov 26, 2019 11:27 pm

Hello David and Phil,

This topic help me a lot, but I have one more question.
I am in a similar case as David, but with 3 MCP23S17 device on the spi bus

Code: Select all

microchip,spi-present-mask = <0x07>;
How do you found the pin number for the gpios property of the gpio-leds driver binding?
All it's ok with value from 0 to 15 for the first controller, but if I try an upper value the gpio-leds binding fail.

It seems we need one more field in the gpios property, but honestly I don't know how to do it.

Thanks for your help, best regards,

Wilfrid

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 2589
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: using mcp23s17 device tree with gpio-leds

Wed Nov 27, 2019 11:02 am

I've spent an hour or so looking at the driver code and crawling through the kernel GPIO infrastructure, and I don't think it's possible. Here's my logic:

1. Although all devices that are found are presented as a single SPI device, they are each registered as independent "gpio_chip"s.

2. A gpio_chip has (amongst other things) a pointer to is Device Tree node, a number of GPIOs, and a function that translates from the "gpiospec" descriptors found in the device tree to an index into the GPIOs exposed by the device. Note that it doesn't include the base of a range - all gpio_chips have GPIOs indexed from 0.

3. The mcp23s08 doesn't specify a translation function, so it inherits the default of_gpio_simple_xlate that checks that the first parameter is less than the number of GPIOs the device supports, and returns it.

4. When another DT node refers to a GPIO, it does so using a "gpiospec" (e.g. "<&gpio 17 0>"). This is passed to gpiochip_find, which uses of_gpiochip_match_node_and_xlate to filter through all the registered GPIO controllers to find one which:
i) has a DT node which matches the first cell ("&gpio")
ii) has a translation function, and
iii) the translation function succeeds.

5. From point 2, all the MCP devices that share an SPI CS/CE inherit the same DT node, which means they will all pass test i). Since they all have the same translation function (of_gpiochip_match_node_and_xlate), and they are all given the same gpiospec to translate, and you aren't meant to mix different size variants, all the sharing devices will either pass or fail the test.

Therefore it's either impossible or I'm too stupid to understand it. I'll ask the maintainers how it's supposed to work.

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 2589
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: using mcp23s17 device tree with gpio-leds

Wed Nov 27, 2019 12:42 pm

Bad news (or good, if you're me) - Linus Walleij, who is responsible for GPIO and pinctrl in the kernel, also thinks this feature is broken:

https://marc.info/?l=linux-gpio&m=157485820503213&w=2

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 2589
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: using mcp23s17 device tree with gpio-leds

Wed Nov 27, 2019 12:45 pm

Can you post your complete overlay? Linus would like an example, and none of the dts files in the kernel make use of the feature.

Return to “Device Tree”