Besides a collection of GPIO pins, the MinnowBoard Max also sports a SPI interface on its 26-pin DIL header.1

The SPI controller is integrated into the CPU, and has a maximum clock rate of 15MHz.

The userspace API

There is a standard Linux SPI userspace API2 but the PXA2xx SPI driver for the E38xx3 does not enable it directly.

In other words no /dev/spi* devices are created:

$ ls /dev/spi*
ls: cannot access /dev/spi*: No such file or directory

The simplest solution I found involved two steps. Firstly compile a suitable kernel: you can grab the config I used4 from GitHub.

Secondly, I compiled low-speed-spidev5 module outside the kernel tree, then loaded it.

$ git clone https://github.com/MinnowBoard/minnow-max-extras.git	
Cloning into 'minnow-max-extras'...					
remote: Counting objects: 40, done.					
remote: Total 40 (delta 0), reused 0 (delta 0)				
Unpacking objects: 100% (40/40), done.					
Checking connectivity... done.						
$ cd minnow-max-extras/modules/low-speed-spidev/			
$ make KERNEL_SRC=~/local-kernel/linux-3.18				
...									
$ sudo insmod low-speed-spidev.ko					

You can check that the driver loaded successfully with dmesg:

$ dmesg									
...									
[79497.388732] low-speed-spidev: module init				
[79497.388757] low-speed-spidev: master=ffff8800797a1000		
[79497.390751] low-speed-spidev: dev=ffff88003774f400			
[79497.390768] low-speed-spidev: spidev registered			

Or just look in /dev:

$ ls -l /dev/spi*							
crw——- 1 root root 153, 0 Dec 19 22:45 /dev/spidev0.0		

Other approaches

I’m not sure about the information in this section: caveat lector!

On ARM based systems, I think one would use Device Tree6 to connect the PXA2xx low-level driver to the spidev driver. This avoids any need to compile code.

The MinnowBoard Max has an Intel CPU though, so rather than Device Tree, the relevant technology is ACPI7

I didn’t explore either of these, because in practice I didn’t want a userspace API at all. Instead I compiled a kernel driver for the SPI LCD display I wanted to drive, and then exported a framebuffer API to userspace.

A bug

The PXA2xx driver in version 3.18 of the linux kernel has a bug which makes it crash.8

Mika Westerberg diagnosed the problem, and provided a patch:

diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c	
index d8a105f76837..3720d84f266b 100644					
— a/drivers/spi/spi-pxa2xx.c						
+++ b/drivers/spi/spi-pxa2xx.c						
@@ -402,8 +402,8 @@ static void giveback(struct driver_data *drv_data)	
			cs_deassert(drv_data);				
	}								
									
-	spi_finalize_current_message(drv_data->master);			
	drv_data->cur_chip = NULL;					
+	spi_finalize_current_message(drv_data->master);			
}									
									
static void reset_sccr1(struct driver_data *drv_data)

Thanks Mika!

Adafruit Python GPIO library

I started adding support for the spidev SPI API to the Adafruit Python GPIO Library.9

You can get the code from GitHub10 but be warned: it’s only a proof of concept and not production quality. I’m not even sure that the API is consistent with the other platforms the library supports.