Peter Bohner

SCD30 on Raspberry Pi OS a.k.a Building additional kernel modules from Debian sources

- 313 words

Preface

Recently, I got myself a Sensirion SCD30 NDIR CO2 sensor, for which Raspberry Pi OS (Debian) does not build the driver. In order to avoid having to compile the entire kernel from source, I did the following:

Getting the kernel

The linux-source-6.18 package provides a tarball of the current kernel sources. Alternatively, you can use apt source to fetch the kernel source. Either way, you need to copy the driver’s source from the archive into a new directory, with the tarball and for the SCD30 driver in particular, you may do this with:

tar xf /usr/src/linux-source-*.tar.xz --wildcards '*/drivers/iio/chemical/scd30*' --strip-components 4

Building the kernel Module out-of-tree

In /lib/modules/<kernelversion>/build, there’s a Makefile for this, to which you can just specify the obj-m variable. To make this more convenient than a shell invocation, you may place this additional Makefile in you driver directory.

obj-m += scd30_core.o scd30_i2c.o

KDIR ?= /lib/modules/$(shell uname -r)/build

all:
        $(MAKE) -C $(KDIR) M=$(CURDIR) modules
install:
        $(MAKE) -C $(KDIR) M=$(CURDIR) modules_install
clean:
        $(MAKE) -C $(KDIR) M=$(CURDIR) clean

Then build and install with:

make
sudo make install
sudo depmod -a
make clean

Why not dkms?

It would introduce a dependency between the driver’s version and the source archive, and I wouldn’t want to fetch the entire source tree every kernel update. I am happy with only updating the driver once it either no longer compiles, or a bug I care about in it gets fixed.

SCD30 Device Tree

Now that the driver is installed, I want to automatically load it when the pi starts up. For this, a device-tree fragment is needed:

/dts-v1/;
/plugin/;
/ {
    compatible = "brcm,bcm2835";
    fragment@0 {
        target = <&i2c1>;
        __overlay__ {
            status = "okay";
            scd30: scd30@61 {
                compatible = "sensirion,scd30";
                reg = <0x61>;
            };
        };
    };
};

It can be built and installed like this:

dtc -@ -I dts -O dtb -o scd30-i2c1.dtbo scd30-i2c1.dts
sudo cp scd30-i2c1.dtbo /boot/firmware/overlays/