Search code examples
raspberry-pilinux-device-driverdevice-tree

Raspberry Pi - SPI device tree changes


I trying to move the SPI bus on a Raspberry Pi 3. I would like to move it from GPIO 7-11 to GPIO pins 22-26. The file "bcm2708_common.dtsi" contains the node for the spi0 bus:

spi0: spi@7e204000 {
    compatible = "brcm,bcm2835-spi";
    reg = <0x7e204000 0x1000>;
    interrupts = <2 22>;
    clocks = <&clk_core>;
    #address-cells = <1>;
    #size-cells = <0>;
    status = "disabled";
    /* the dma channels */
    dmas = <&dma 6>, <&dma 7>;
    dma-names = "tx", "rx";
    /* the chipselects used - <0> means native GPIO
     * add more gpios if necessary as <&gpio 6 1>
     * (but do not forget to make them output!)
     */
    cs-gpios = <0>, <0>;
};

The spi is configured in the top-level dts file "bcm2710-rpi-3-b.dts":

&gpio {
    spi0_pins: spi0_pins {
        brcm,pins = <7 8 9 10 11>;
        brcm,function = <4>; /* alt0 */
    };
};

&spi0 {
    pinctrl-names = "default";
    pinctrl-0 = <&spi0_pins>;
    cs-gpios = <0 0>;

    spidev@0{
        compatible = "spidev";
        reg = <0>;  /* CE0 */
        #address-cells = <1>;
        #size-cells = <0>;
        spi-max-frequency = <500000>;
    };

    spidev@1{
        compatible = "spidev";
        reg = <1>;  /* CE1 */
        #address-cells = <1>;
        #size-cells = <0>;
        spi-max-frequency = <500000>;
    };
};

Is reconfiguring the spi pins as simple as changing the gpio entry to this or is there something more that I need to do?

&gpio {
    spi0_pins: spi0_pins {
        brcm,pins = <22 23 24 25 26>;
        brcm,function = <4>; /* alt0 */
    };
};

Solution

  • No. you can not just change the pin numbers in DTSI and get it to change.

    Long answer: The brcm,pins field is just information for driver to refer to, if hardware does not support the pins you write there, you can not get it to work. On the Rpi 3b, pins 7,8,9,10,11 are supported as SPI i.e they can be multiplexed as SPI (the field brcm,function tells which multiplex mode to set pins in).

    Now, also if you search for BCM2835 ARM peripheral you will find on page 152 the following:

    The BCM2835 devices has only one SPI interface of this type. It is referred to in all the documentation as SPI0. It has two additional mini SPI interfaces (SPI1 and SPI2). The specifiation of those can be found under 2.3 Universal SPI Master (2x).

    So, the SoC on Rpi itself does not support other spi on any other pin.

    Now for the second sentence of the above quote

    It has two additional mini SPI interfaces (SPI1 and SPI2). The specifiation of those > can be found under 2.3 Universal SPI Master (2x).

    If you dig in to bcm283x.dtsi, you will find that both those mini spis are named SPI1 and SPI2. gpio pins assigned for them are given as spi1_gpio16 and spi2_gpio40 which use pins :

    spi1_gpio16: spi1_gpio16 {
    brcm,pins = <16 17 18 19 20 21>;
    brcm,function = <BCM2835_FSEL_ALT4>;
    };
    spi2_gpio40: spi2_gpio40 {
    brcm,pins = <40 41 42 43 44 45>;
    brcm,function = <BCM2835_FSEL_ALT4>;
    };
    

    so again not the pins you want to use.

    You may go for bit banging spi if you are really really in a fix and can not use anything else