SPI: chipselect 0 already in use

Hi, i’ve encounter an issue on loading custom spi driver. I look through some similar topics, but can’t find an answer.
Here is my setup:

  1. uEnv.txt:
    uEnv.txt (1.6 KB)
  2. Boot log:
    BBB-boot-output.txt (3.9 KB)

Here are steps:

  1. Create simple spi device driver to read adxl345 ID.
  2. Compile it on Ubuntu machine and transfer to BBB.
  3. Load .ko on BBB, but got a message:
    omap2_mcspi 48030000.spi: chipselect 0 already in use.

NOTE: i’ve enabled spidev in /boot/uEnv.txt in 2 ways (one at a time):
in the first case, there is /dev/spidev0.0, in the second there is not. I don’t know the difference between these two .dtbo.
What i missed? How to understand which peripheral uses spi chip select?
Will appreciate any help.


→ loads as shown:
uboot_overlays: loading /boot/dtbs/5.10.168-ti-r72/overlays/BB-SPIDEV0-00A0.dtbo

Whereas: uboot_overlay_addr6=/lib/firmware/BB-SPIDEV0-00A0.dtbo

Would load from /lib/firmware/


That is clear, the question is which one to use?
In case of uboot_overlay_addr6=/lib/firmware/BB-SPIDEV0-00A0.dtbo the /dev/spidev0.x is present, in case of uboot_overlay_addr6=BB-SPIDEV0-00A0.dtbo the /dev/spidev0.x is not present.

Where did you copy your custom BB-SPIDEV0-00A0.dtbo file too?

/lib/firmware/ is the legacy generic location, /boot/dtbs/<uname -r>/overlays/ is the kernel specific location.


ok, thanks for the answer.
as for original question, omap2_mcspi 48030000.spi: chipselect 0 already in use, what is the reason for that message?

share your overlay, based on your boot log i see nothing wrong…

BB-SPIDEV0-00A0.dts (2.4 KB)
this file is located:

Check that spidev is loaded…

debian@23-am335x-bbb:~$ sudo beagle-version
dogtag:[BeagleBoard.org Debian Bullseye IoT Image 2022-12-01]
bootloader:[microSD-(push-button)]:[/dev/mmcblk0]:[U-Boot SPL 2022.04-gbaca7b46 (Jan 15 2024 - 19:59:28 +0000)]:[location: dd MBR]
UBOOT: Booted Device-Tree:[am335x-boneblack-uboot.dts]
UBOOT: Loaded Overlay:[BB-SPIDEV0-00A0.kernel]
/boot/uEnv.txt Settings:
pkg check: to individually upgrade run: [sudo apt install --only-upgrade <pkg>]
groups:[debian : debian adm kmem dialout cdrom floppy audio dip video plugdev users systemd-journal input bluetooth netdev i2c gpio admin tisdk weston-launch cloud9ide]
cmdline:[console=ttyS0,115200n8 root=/dev/mmcblk0p1 ro rootfstype=ext4 rootwait coherent_pool=1M net.ifnames=0 rng_core.default_quality=100]
dmesg | grep remote
[    5.915153] remoteproc remoteproc0: wkup_m3 is available
[   34.642359] remoteproc remoteproc0: powering up wkup_m3
[   34.651186] remoteproc remoteproc0: Booting fw image am335x-pm-firmware.elf, size 217148
[   34.702165] remoteproc remoteproc0: remote processor wkup_m3 is now up
[   41.211312] remoteproc remoteproc1: 4a334000.pru is available
[   41.296667] remoteproc remoteproc2: 4a338000.pru is available
dmesg | grep pru
[   41.211312] remoteproc remoteproc1: 4a334000.pru is available
[   41.296667] remoteproc remoteproc2: 4a338000.pru is available
dmesg | grep pinctrl-single
[    4.483312] pinctrl-single 44e10800.pinmux: 142 pins, size 568
dmesg | grep gpio-of-helper
dmesg | grep wlcore
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
debian@23-am335x-bbb:~$ ls /dev/spi*
ls: cannot access '/dev/spi*': No such file or directory
debian@23-am335x-bbb:~$ lsmod | grep spi
debian@23-am335x-bbb:~$ sudo modprobe spidev
debian@23-am335x-bbb:~$ lsmod | grep spi
spidev                 24576  0
debian@23-am335x-bbb:~$ ls /dev/spi*
/dev/spidev0.0  /dev/spidev0.1


once i enabled the line in /boot/uEnv.txt:
spidev is loaded:

ls -l /dev/spi*
crw------- 1 root root 153, 1 Mar  7 00:23 /dev/spidev0.0
crw------- 1 root root 153, 0 Mar  7 00:23 /dev/spidev0.1

anyway, on attempt to load spi driver got the message:
omap2_mcspi 48030000.spi: chipselect 0 already in use
lsmode output:

Module                  Size  Used by
pru_rproc              28672  0
irq_pruss_intc         20480  0
pvrsrvkm              368640  0
pruss                  20480  1 pru_rproc
pm33xx                 20480  0
evdev                  24576  1
wkup_m3_ipc            20480  1 pm33xx
uio_pdrv_genirq        20480  0
uio                    20480  1 uio_pdrv_genirq
cpufreq_dt             20480  0
spidev                 24576  0

Is it possible to disable /dev/spidev0.0? If so, what is the proper way to do this?

how are you loading the spi driver? spidev is already loaded…


using command:
sudo insmod .ko
here is my custom driver source:
adxl345-driver.c (1.8 KB)

So do you want to use spidev or adxl345, it’s your choice but you can only pick one…

I see what you are doing now, trying to use spidev to setup the pins and then use adxl345, nope… You need to add the adxl345 bindings to the spidev overlay or create your own overlay to load adxl345.


Is it possible to disable /dev/spidev0.0 ?

Yeah, don’t load the spidev overlay…

You’ll need to create a new overlay just for the adxl345

As far as I understand there are two types of SPI drivers in Linux:

  • controller driver;
  • protocol driver.

Initially, I developed protocol driver, in this case I used spidev
as controller driver. Protocol driver uses ioctl() system call
to setup SPI and get access to the adxl345. In this case, I don’t
need to load the driver, it works in the user space.

Then, I decided to dive deeper…

I still rely on spidev as controller driver and used function
spi_busnum_to_master() to get access to the SPI bus. In this case,
on load the driver i get the message that chip select pin is already in use.

So, now I’m confused a bit how to handle this.

What i see here (further steps):

  1. Create character device adxl345 under /dev/adxl345.
  2. Should master be allocated and registered? using spi_alloc_master() and spi_register_master().
  3. Create new slave device using: spi_new_device() and spi_setup().
    I assume it is better to do based on device tree overlay (will be my next step), but I want to do this without it.

Please, correct me if I missed smth.

The adxl345 device tree: adi,adxl345.yaml « accel « iio « bindings « devicetree « Documentation - kernel/git/torvalds/linux.git - Linux kernel source tree

adxl345 driver: accel « iio « drivers - kernel/git/torvalds/linux.git - Linux kernel source tree

thus grabbing: src/arm/overlays/BB-SPIDEV0-00A0.dts · v5.10.x-ti-unified · BeagleBoard.org / BeagleBoard-DeviceTrees · GitLab


#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pinctrl/am33xx.h>
#include <dt-bindings/interrupt-controller/irq.h>

 * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
&{/chosen} {
	overlays {
		BB-SPI-ADXL345.kernel = __TIMESTAMP__;

 * Free up the pins used by the cape from the pinmux helpers.
&ocp {
	P9_17_pinmux { status = "disabled"; };	/* P9_17 (A16) spi0_cs0.spi0_cs0 */
	P9_18_pinmux { status = "disabled"; };	/* P9_18 (B16) spi0_d1.spi0_d1 */
	P9_21_pinmux { status = "disabled"; };	/* P9_21 (B17) spi0_d0.spi0_d0 */
	P9_22_pinmux { status = "disabled"; };	/* P9_22 (A17) spi0_sclk.spi0_sclk */

&am33xx_pinmux {
	bb_spi0_pins: pinmux_bb_spi0_pins {
		pinctrl-single,pins = <
			AM33XX_PADCONF(AM335X_PIN_SPI0_SCLK, PIN_INPUT, MUX_MODE0)	/* P9_22 (A17) spi0_sclk.spi0_sclk */
			AM33XX_PADCONF(AM335X_PIN_SPI0_D0, PIN_INPUT, MUX_MODE0)	/* P9_21 (B17) spi0_d0.spi0_d0 */
			AM33XX_PADCONF(AM335X_PIN_SPI0_D1, PIN_INPUT, MUX_MODE0)	/* P9_18 (B16) spi0_d1.spi0_d1 */
			AM33XX_PADCONF(AM335X_PIN_SPI0_CS0, PIN_INPUT, MUX_MODE0)	/* P9_17 (A16) spi0_cs0.spi0_cs0 */

&spi0 {
	#address-cells = <1>;
	#size-cells = <0>;

	status = "okay";
	pinctrl-names = "default";
	pinctrl-0 = <&bb_spi0_pins>;

	accelerometer@0 {
		compatible = "adi,adxl345";
		reg = <0>;
		spi-max-frequency = <16000000>;

so that’s what i’d do…


Hi, is it possible define spi device without using DT?

DT is way easier, as it includes the spi node and spi pins…


yeah, that is true, but I’d like to try add device in case if kernel is not supporting DT.
I tried to call function spi_busnum_to_master() , but it returns NULL means there is no master available on the bus.

Your calling it while “spidev” has the node… So the spi bus is now locked up by spidev…