Skip to content

Instantly share code, notes, and snippets.

@mcbridejc
Last active February 25, 2024 17:20
Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save mcbridejc/d060602e892f6879e7bc8b93aa3f85be to your computer and use it in GitHub Desktop.
Save mcbridejc/d060602e892f6879e7bc8b93aa3f85be to your computer and use it in GitHub Desktop.
How to add or change SPI chip select pins on raspberry PI with device tree overlay

The raspberry pi SPI0 by default has 2 CS pins configured. The SPI driver in the kernel uses GPIOS toggled by software, rather than hardware controlled chip selects. This means that any GPIO can be used for a chip select, and any number of them can be supported concurrently. All of these setup for the SPI driver is defined in the device tree, and we can use device tree overlays stored in /boot to dynamically configure the device tree.

The attached example creates a SPI device with 5 CS pins, on GPIO 8, 7, 1, 5, and 6.

To compile it to a binary: dtc -@ -I dts -O dtb -o spi-cs-extend.dtbo spi-cs-extend.dts

Then place spi-cs-extend.dtbo into /boot/overlays and add the following line to your /boot/config.txt: dtoverlay=spi-cs-extend.

After your next reboot, you should find /dev/spi0.2, /dev/spi0.3, and /dev/spi0.4 have been created.

/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835";
fragment@0 {
target = <&spi0_cs_pins>;
frag0: __overlay__ {
brcm,pins = <8 7 1 5 6>;
};
};
fragment@1 {
target = <&spi0>;
frag1: __overlay__ {
#address-cells = <1>;
#size-cells = <0>;
cs-gpios = <&gpio 8 1>, <&gpio 7 1>, <&gpio 1 1>, <&gpio 5 1>, <&gpio 6 1>;
status = "okay";
spidev0_2: spidev@2 {
compatible = "spidev";
reg = <2>;
#address-cells = <1>;
#size-cells = <0>;
spi-max-frequency = <125000000>;
};
spidev0_3: spidev@3 {
compatible = "spidev";
reg = <3>;
#address-cells = <1>;
#size-cells = <0>;
spi-max-frequency = <125000000>;
};
spidev0_4: spidev@4 {
compatible = "spidev";
reg = <4>;
#address-cells = <1>;
#size-cells = <0>;
spi-max-frequency = <125000000>;
};
};
};
};
@jdfin
Copy link

jdfin commented Mar 17, 2022

Thanks for taking the time to post - worked for me first time on Pi Zero W, adding spidev0.2 with cs on gpio 25.

@mcbridejc
Copy link
Author

Great I'm glad it helped! Thanks for letting me know.

@TomoBiDiK
Copy link

Thanks for the job! that's exactly what I was looking for. can you pls explain me how can these new CS be combined with the bcm2835 library and its "bcm2835_spi_chipSelect" function?

@TheJoshGriffith
Copy link

TheJoshGriffith commented Jul 1, 2022

Thanks for sharing, and a note to anyone looking to use this... To change the pin numbers is quite obvious, but to have 3 chip selects I had to modify line 11 and 21 by changing the BCM pin numbers, then lines 26, 34, and 42 to change the register to 0, 1, and 2. Also, 24, 32, and 40 needed their indexes changing. My finished overlay is as follows and works a treat.

/dts-v1/;
/plugin/;


/ {
        compatible = "brcm,bcm2835";

        fragment@0 {
                target = <&spi0_cs_pins>;
                frag0: __overlay__ {
                        brcm,pins = <4 14 15>;
                };
        };

        fragment@1 {
                target = <&spi0>;
                frag1: __overlay__ {
                        #address-cells = <1>;
                        #size-cells = <0>;

                        cs-gpios = <&gpio 4 1>, <&gpio 14 1>, <&gpio 15 1>;
                        status = "okay";

                        spidev0_0: spidev@0 {
                                compatible = "spidev";
                                reg = <0>;
                                #address-cells = <1>;
                                #size-cells = <0>;
                                spi-max-frequency = <125000000>;
                        };


                        spidev0_1: spidev@1 {
                                compatible = "spidev";
                                reg = <1>;
                                #address-cells = <1>;
                                #size-cells = <0>;
                                spi-max-frequency = <125000000>;
                        };


                        spidev0_2: spidev@2 {
                                compatible = "spidev";
                                reg = <2>;
                                #address-cells = <1>;
                                #size-cells = <0>;
                                spi-max-frequency = <125000000>;
                        };
                };
        };
};

@zultekeng
Copy link

Great work guys, I have 20 spi devices to control.... Wanting to use the RPi Zero2 for my project, is this also compatible with the BCM2710A1, if so is it just a matter of modifying the "compatible = " line to add the required processor? Thanks for your help

@beartronix
Copy link

Great work, I love it! I had to remove GPIO1 from the list though, as I'm using the PoE Hat Plus Fan, which uses i2c0 (GPIO1 and GPIO0) for PWM control over i2c.

For reference: rpi-poe-plus-overlay.dts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment