The NXP i.MX6QP CPU has:

  • five SPI ports on the Quad/Dual variants.

  • four SPI ports on the Solo/DualLite variants.

On the ConnectCore 6 Plus system-on-module:

  • All SPI ports are available on the LGA pads (multiplexed with other functionality).

On the ConnectCore 6 Plus SBC:

  • SPI1 is available through an expansion connector.

Kernel configuration

You can manage the SPI driver support through the kernel configuration option:

  • Freescale i.MX SPI controllers interface (CONFIG_SPI_IMX)

This option is enabled as built-in on the ConnectCore 6 Plus SBC kernel configuration file.

Kernel driver

The SPI bus driver for the ConnectCore 6 Plus is located at drivers/spi/spi-imx.c.

The Linux driver supports the SPI bus in master mode only, and using PIO mode.

Device tree bindings and customization

The i.MX6 SPI interface device tree binding is documented at Documentation/devicetree/bindings/spi/fsl-imx-cspi.yaml.

The SPI interfaces are defined in the i.MX6 CPU, ConnectCore 6 Plus, and ConnectCore 6 Plus SBC device tree files.

Example: SPI1

Definition of the bus

Common ConnectCore 6 Plus device tree
ecspi1: ecspi@2008000 {
	#address-cells = <1>;
	#size-cells = <0>;
	compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
	reg = <0x02008000 0x4000>;
	interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
	clocks = <&clks IMX6QDL_CLK_ECSPI1>,
	         <&clks IMX6QDL_CLK_ECSPI1>;
	clock-names = "ipg", "per";
	dmas = <&sdma 3 7 1>, <&sdma 4 7 2>;
	dma-names = "rx", "tx";
	status = "disabled";
};

IOMUX configuration

Common ConnectCore 6 Plus device tree
ecspi1 {
	pinctrl_ecspi1: ecspi1 {
		fsl,pins = <
			MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
			MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
			MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
			MX6QDL_PAD_EIM_EB2__GPIO2_IO30  0x100b1
			MX6QDL_PAD_KEY_COL2__GPIO4_IO10 0x100b1
			MX6QDL_PAD_EIM_CS0__GPIO2_IO23  0x100b1
		>;
	};
};

Bus enabling

ConnectCore 6 Plus SBC device tree
&ecspi1 {
	fsl,spi-num-chipselects = <2>;
	cs-gpios = <&gpio2 30 GPIO_ACTIVE_HIGH>,<&gpio4 10 GPIO_ACTIVE_HIGH>;
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_ecspi1>;
	status = "okay";
};

SPI user space usage

The SPI bus cannot be accessed directly from user space. Instead, it is accessed via the SPI client drivers. However, a special sample client driver allows raw access to the SPI bus.

SPI device interface

The Linux kernel offers a sample client driver called spidev that gives you read and write data access to the SPI bus through the /dev interface:

You can find this driver under the kernel configuration option User mode SPI device driver support (CONFIG_SPI_SPIDEV).

On Digi Embedded Yocto, this driver is enabled as a loadable module. The default device tree includes the spidev node in the device tree as an SPI device hanging from your SPI bus:

&ecspi1 {
	fsl,spi-num-chipselects = <2>;
	cs-gpios = <&gpio2 30 GPIO_ACTIVE_HIGH>,<&gpio4 10 GPIO_ACTIVE_HIGH>;
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_ecspi1>;
	status = "okay";
	spidev@0 {
		compatible = "rohm,dh2228fv";
		reg = <0>;
		spi-max-frequency = <4000000>;
		status = "okay";
	};
};

To use it, load the spidev module from user space:

# modprobe spidev
Note that spidev is not a real hardware SPI device but a detail of how Linux controls a device.

Linux will create a device node in the form /dev/spidevX.Y device node where X corresponds to the SPI bus index, starting at zero, and Y corresponds to the SPI bus chip select, starting at zero. For example, the ConnectCore 6 Plus SBC peripheral SPI1 bus would be accessed through device node /dev/spidev0.0.

Sample application

An example application called apix-spi-example is included in the dey-examples-digiapix recipe (part of dey-examples package) of the meta-digi layer. This application is an example of how to write data to an external EEPROM (24FC1026) and read it back using Digi APIx library on the ConnectCore 6 Plus platform.

Go to GitHub to see the application instructions and source code.

See SPI API for more information about the SPI APIx.