spi: bcm2835: strange observation with cs_gpios low after reboot

Martin Sperl martin at sperl.org
Sat Mar 28 05:12:02 PDT 2015

I found the following strange situation with cs_gpios after a reboot
of my raspberry-pi.

Essentially on first load one of my devices does not get detected.
Only when I reload the spi-bcm2835 driver the second device gets
correctly detected.

The reason behind this is that at one point (probably during 
pin-control) the GPIOs that are set to output, but the level is
not modified in the register, so it is pulled low.

They only get set to the correct polarity when spi_setup is running
during the initialization of the device itself, which results in
the 2 identical devices getting configured at the same time while the
first device is running with spi_setup having run while the second
is still pending a call to spi_setup which sets up gpio with the 
correct polarity and thus is also responding even if not intended.

The second time I load the spi-bcm2835 driver it works fine
as the levels have been set already and the levels are not modified.

Is this something that has been observed before?

My dt has the following:

&gpio {
	spi_cs_pins: spi_cs_pins {
		brcm,pins = <4 5 6>;
		brcm,function = <1>; /* output */

&spi {
	cs-gpios = <0>, <0>, <&gpio 6 0>, <&gpio 5 0>, <&gpio 4 0>;

I have also tried:
	cs-gpios = <0>, <0>, <&gpio 6 1>, <&gpio 5 1>, <&gpio 4 1>;
but it makes no difference.

The following in my driver solves the problem for now, but ignores
the configured CS polarity initially, but it handles the "typical"
case of normal CS polarity:

static int spi_initialsetup_gpio(struct spi_master* master)
	int i;
	bool level;
	if (!master->cs_gpios)
		return 0;

	for (i = 0; i < master->num_chipselect; i++) {
		if (gpio_is_valid(master->cs_gpios[i])) {
			/* actually we need to figure out the
			 * configured CSPOL of that device here,
			 * not sure how to do that...
			level = true;
			gpio_set_value(master->cs_gpios[i], level);
	return 0;

and call it inside spi_probe after spi_register_master.

I wonder if this is some oversight either on the spi side or on
the bcm2835-pinctrl side.

Note that the same thing may happen if a spi-device is:
	status = "disabled";
in the device-tree but still connected to the bus electrically.

In my experience this may make the bus unusable, but that might
get attributed to a bad device-tree itself - still it is a possible
pitfall that we might want to avoid...


More information about the linux-rpi-kernel mailing list