SPI - expander using GPIO configuration in device tree

We made a Nano carrier board with two IMX174 imagers connected to SPI0.
To convert from Sony SubLVDS to CSI-2 we implemented a Crosslink FPGA for each of the two IMX174.
Furthermore there is one additional sensin


g device on the SPI bus.
So we have got a sum of 5 slaves at the SPI bus.
We used a SN74LVC138 1-of-8 decoder to expand SPI_CS0* ( pin 95 of Nano ) . The A, B, C - inputs of 74LVC138 are connected to GPIOs PC.04, PE.06 and PZ.00 .
We can communicate with all five SPI-bus slaves in user mode with a modified spidev_test.c using dev/spi/spidev0.0 where we set the GPIOs for the 74LVC138 according to our desired slave.
But when we insert a kernel module imx174.o on boot, we loose spidev0.0 an can no longer access the Crosslink FPGA in user mode.

So the question is: Can it be done in the device tree to define SPI-busses dev/spi/spidev0.0 through /dev/spidev/spidev0.4 an tell the system that these five busses need the setting of GPIOs PC.04, PE,.06 and PZ.00 in a well defined manner ?
I.e. :
spidev0.0 is spidev0 with PC.04=0, PE.06=0, PZ.00 = 0
spidev0.1 is spidev0 with PC.04=1, PE.06=0, PZ.00 = 0
spidev0.2 is spidev0 with PC.04=0, PE.06=1, PZ.00 = 0
spidev0.3 is spidev0 with PC.04=1, PE.06=1, PZ.00 = 0
spidev0.4 is spidev0 with PC.04=0, PE.06=0, PZ.00 = 1
Best regards
Andreas

1 Like

We found a workaround solution for the problem:
We removed the address decoder ( SN74LVC138) from the prototype board

and configure the DT to control the SPI-CS-signals directly using GPIO:
With the DT entry

spi@7000d400 { /* SPI 1 to 40 pin header */
cs-gpios = <&gpio TEGRA_GPIO(C, 3) 0>, <&gpio TEGRA_GPIO(C, 4) 0>, <&gpio TEGRA_GPIO(Z, 0) 0>, <&gpio TEGRA_GPIO(E, 6) 0>, <&gpio TEGRA_GPIO(DD, 0) 0>;
num-cs = <5>;
status = “okay”;
spi@0 {
compatible = “spidev”;
reg = <0x0>;
spi-max-frequency = <33000000>;
chipselect-gpio = <&gpio TEGRA_GPIO(C, 3) 0>;
nvidia,rx-clk-tap-delay = <7>;
};

  spi@1 {
  	compatible = "spidev";
  	reg = <0x1>;
  	spi-max-frequency = <33000000>;
  	chipselect-gpio = <&gpio TEGRA_GPIO(C, 4) 0>;
  	nvidia,rx-clk-tap-delay = <7>;		
  };
  spi@2 {
  	compatible = "spidev";
  	reg = <0x2>;
  	spi-max-frequency = <33000000>;
  	chipselect-gpio = <&gpio TEGRA_GPIO(Z, 0) 0>;
  	nvidia,rx-clk-tap-delay = <7>;		
  };
  
  spi@3 {
  	compatible = "spidev";
  	reg = <0x3>;
  	spi-max-frequency = <33000000>;
  	chipselect-gpio = <&gpio TEGRA_GPIO(E, 6) 0>;
  	nvidia,rx-clk-tap-delay = <7>;		
  };
  spi@4 {
  	compatible = "spidev";
  	reg = <0x3>;
  	spi-max-frequency = <33000000>;
  	chipselect-gpio = <&gpio TEGRA_GPIO(DD,0) 0>;
  	nvidia,rx-clk-tap-delay = <7>;		
  };
};

Blockquote
we get spidev0.0…spidev0.5 and we can see the CS-signals at our scope.

1 Like

Glade to figure the solution.
Yes, using GPIO as chip select for 3 and above device is correct solution.