McSPI SPIDEV - GPIO as Chip Select

Is there anyway to use GPIO on the beaglebone as chip selects for SPIDEV?

I have come across some (out of date, unfinished) attempts but I don’t have enough kernel programming knowledge (yet) to be able to bodge them in, and don’t know if a solution has been added since?


HW wise, yes, but it requires external HW. You use the CS to select a decoder where the other GPIO pins set the address. Use something like an L138 device and it will give you 8 CS off of one SPI_CS and 3 GPIO pins.



So there is no way to use the exisitng GPIO on the BeagleBone as additional chip selects? it’s a custom SPI protocol I am developing and I want to use the chip selects as a read/write lines.


spidev-2.0 - read line - real chip select (when low = read)-----------

------- r/w line on hw
spidev-2.1 - write line gpio chip select (when low = write)------------

So it’s basically half duplex spi with seperate read and write lines to an FPGA. At the moment I am toggling GPIO to get the read/write lines but if I could use Chip Selects then it would be a lot faster and efficient.

I currently use a patch to enabled SPIDEV in the kernel, so this is where I would image I could select additional GPIO to work as additional chip selects.

Have I got myself muddled?

Like this:

About halfway down the page:

i am not sure if having the CS so out of sync with the clock and data will do to all those SPI devices out there. Some may be OK and some not. If you are just bit banging all the signals, it will be much slower and probably OK, but it depends on the devices on the other end.


[cleaned up top post for easier reply]

> Ok,
> So there is no way to use the exisitng GPIO on the BeagleBone as
> additional chip selects? it's a custom SPI protocol I am developing and I
> want to use the chip selects as a read/write lines.

Ok, let's be careful on terminology here. First we're talking SPI in
which the notion of a chip select has a fundamental definition with
regards to standard SPI operation.

Next, McSPI is not a general purpose serial data engine. It's designed
to generate de facto standard SPI protocol...period. So those hardware
chip selects can't be arbitrarily repurposed to do non-SPI things.

Let's talk about that. Most SPI connected chips have some out-of-band
signals as you are describing. These are totally out of the scope of
what you should expect to drive with the McSPI on Beaglebone.

Like this:

About halfway down the page:

To make use of this feature, set chip_select = MAX_CTRL_CS + a proper GPIOnumber.

static struct spi_board_info
        .chip_select = GPIO_PFXX + MAX_CTRL_CS, /* GPIO controlled SSEL */

No. This is the blackfin SPI master driver. What they are describing
here is use of GPIOs as additional SPI protocol chip selects. That is,
if you are out of hardware chipselects (or maybe you needed that pad
pinmuxed to something else), on the blackfin driver you can flag a gpio
to be bit-banged by their driver as the chip select for SPI transfers.
This is not for arbitrary use for device specific R/W_ pins or similar.

Incidentally, the spi-omap2-mcspi.c driver does not support a GPIO as a
chip select.

Since you are doing a userspace driver (guaranteed to be slow for your
case of SPI and GPIO use), the proper approach is to assert your R/W
GPIO via sysfs and then do the spidev transfer.

An optimized approach is to write a proper kernel driver. Many many
examples exist. The same principles hold in this case, but the
performance of the SPI transfers and GPIO latency is much better. You
will assert a GPIO R/W pin then execute your spi_read()/write() command.
is an example of a kernel SPI peripheral driver with the same type of
protocol you describe implemented...only it's the data/command signal
being asserted before each transfer.


From a hardware perspective, can I suggest the use of something like a 74HC138?
tie the existing SPI “CS” line to one of the 74CH138 enable lines, then connect 3 GPIO lines to the three address lines on the 74HC138.
Use pull up resistors on the 8 outputs of the 74HC138.
Then before you use the SPI, set the address of the Chip Select your want on the 3 GPIO lines.

That should negate the need to mess around with custome drivers.

This would only work with devices where the Chip Select is active LOW.

Feel free to correct me if I’m wrong or if I mis-understood the problem.


Matt, thank you for your very clear repsonse. I am indeed attempting to ‘miss-use’ chip selects as ‘out of protocol’ custom spi read/write lines. I am currently bitbanging the gpio lines through sysfs to give me my required customisations but as you mentioned it is slow. To the degree of the SPI transfer taking ~10usecs and the gpio ‘toggle’ requring ~65usecs either side.

I will look at the driver you suggested and see if I can implement it as required.

Thank you for the clarification.