Dragonboard410c Debian img 283 enabling SPI


I am trying to enable the SPI into the Dragonboard410c using the 283 image version without success.

Before opening this post I found the message

How to enable spi and access it in Debian os

(please note that in that thread the forum formatter changes code characters as " to the sequence &quot;, also for characters ‘<’ & ‘>’)
and I further tried at least two attempts.

The first thing I done is to downloaded the 4.9.56 kernel as listed here.

1st attempt

I donwloaded the Peripherals Programming Guide Linux Android, with SPI section included.
This guide suggests to modify the following files:


adding the following content:

spi0 = &spi_0; /* SPI0 controller device */
spi_0: spi@78b7000 { /* BLSP1 QUP3 */
compatible = "qcom,spi-qup-v2";
#address-cells = <1>;
#size-cells = <0>;
reg-names = "spi_physical", "spi_bam_physical";
reg = <0x78b7000 0x600>,
<0x7884000 0x23000>;
interrupt-names = "spi_irq", "spi_bam_irq";
interrupts = <0 97 0>, <0 238 0>;
spi-max-frequency = <50000000>;
pinctrl-names = "default", "sleep";
pinctrl-0 = <&spi0_default &spi0_cs0_active>;
pinctrl-1 = <&spi0_sleep &spi0_cs0_sleep>;
clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>,
<&clock_gcc clk_gcc_blsp1_qup3_spi_apps_clk>;
clock-names = "iface_clk", "core_clk";
qcom,infinite-mode = <0>;
qcom,bam-consumer-pipe-index = <8>;
qcom,bam-producer-pipe-index = <9>;
qcom,master-id = <86>;
lattice,spi-usb@0 {
compatible = "lattice,ice40-spi-usb";
reg = <0>;
spi-max-frequency = <50000000>;
spi-cpol = <1>;
spi-cpha = <1>;
core-vcc-supply = <&pm8916_l2>;
spi-vcc-supply = <&pm8916_l5>;
qcom,pm-qos-latency = <2>;
lattice,reset-gpio = <&msm_gpio 3 0>;
lattice,config-done-gpio = <&msm_gpio 1 0>;
lattice,vcc-en-gpio = <&msm_gpio 114 0>;
lattice,clk-en-gpio = <&msm_gpio 0 0>;
clocks = <&clock_rpm clk_bb_clk2_pin>;
clock-names = "xo";
pinctrl-names = "default", "sleep";
pinctrl-0 = <&ice40_default>;
pinctrl-1 = <&ice40_sleep>;

Then modifying the file kernel/arch/arm/boot/dts/qcom/<chipset>-pinctrl.dtsi which for Linux 4.9.56 linaro kernel should be


&soc {
tlmm_pinmux: pinctrl@1000000 {
spi0_active {
qcom,pins = <&gp 8>, <&gp 9>, <&gp 11>;
qcom,num-grp-pins = <3>;
qcom,pin-func = <1>;
label = "spi0-active";
/* active state */
spi0_default: default {
drive-strength = <12>; /* 12 MA */
bias-disable = <0>; /* No PULL */
spi0_suspend {
qcom,pins = <&gp 8>, <&gp 9>, <&gp 11>;
qcom,num-grp-pins = <3>;
qcom,pin-func = <0>;
label = "spi0-suspend";
/* suspended state */
spi0_sleep: sleep {
drive-strength = <2>; /* 2 MA */
bias-pull-down; /* pull down */

However, the kernel compilation fails because the content of the modifications seems wrong. In fact, in the second modificatioin seems to be missing at least one bracket, and this is not the only error the kernel claims.

2nd attempt

Always referring to the post [How to enable spi and access it in Debian os Message 47 ]How to enable spi and access it in Debian os - #47 by ljking)

two modifications are suggested, one for device-tree and the other for kernel driver.

However, after successfully compiling the kernel, creating the img file file with mkbootimg and loading it using fastboot, the kernel does not recognize any more the Wifi IC.

So do you have any OFFICIAL patch available rather than an unofficial old thread ?
Could you please provide reliable instructions to enable the SPI ?

Thank you in advance,

So do you have any OFFICIAL patch available rather than an unofficial
old thread ?
Could you please provide reliable instructions to enable the SPI ?

The official doc is here:

Saying its official is not strictly the same as saying that it works
(for a start please interpret “16.06” as “16.06 or later”) but I don’t
think anything significant has changed in the way you must describe SPI
in the device tree.


1 Like

Thank you @danielt.
I am going to test it and reports the results.


No worries.

FYI I did throw in a quick bug report about the versioning: https://github.com/96boards/documentation/issues/187

Hello @danielt,

The SPI now transmists and I can see the data and the clock signals on my oscilloscope.
Just a lat question: is it needed some additional code modifications to drive the CS via hardware ?

The old post I linked mentions about driver code modifications (I tested it without success), and I don’t see any modification done to the device-trees from the official doc.


Hmnnn… I don’t have anything with SPI to hook up so I might have to give you another “homework” answer.

There are three ways to manage chip select:

  1. Do it in software in userspace. This sucks in almost every possible way because it requires userspace to know all sorts of crazy non-portable mappings from spi devices to GPIO bits… but some of the libmraa examples floating around the web do actually pretend this is the right thing to do (and it does work, its just not nice).

  2. Do it in software in the kernel. This is very useful if you have multiple devices on the SPI bus and/or the hardware implementation is broken (or just so badly documented you don’t know how to use it properly :wink: ) .

  3. Do it in hardware.

The best “documentation” I have to hand is a patch from @ljking that transitions a DT from using the software-in-the-kernel approach to fully utilizing the hardware: RE: SPI fix needed in kernel (DragonBoard 410c) — Linux SPI .

I confess I haven’t looked at the 17.09 DT to find out how it is currently configured but Laurence’s patch should help you find your bearings.

1 Like

After struggling a while with device-trees and attempting to make CS work via kernel-space, I decided to use GPIO funcionality to put it at logic state 0 when before and after transmit.

It’s something I have already done before with other devices.
The problem of pin mapping can be easily solved with a good programming technique.
I don’t like a lot using GPIO CS, but it offers many degrees of freedom (in therms of slave devices).