SPIGEN(4)
π SPIGEN(4) π
okay bestie so this is spigen(4), straight out of the Kernel Interfaces Manual π it's a kernel driver, it's about SPI, and by the end of this page you're gonna be its number one fan, fr fr.
β¨ NAME β¨
spigen β the SPI generic I/O device driver. that's the whole name, short, sweet, iconic π
πΈ SYNOPSIS πΈ
so like, if you wanna bake this driver into the kernel (permanent commitment energy π), you drop these lines into your kernel configuration file:
device spi
device spibus
device spigen
OR β and this is the lowkey easier route β you can load it as a module at boot time by putting this line in loader.conf(5):
spigen_load="YES"
pick your fighter, both slay π
π¦ DESCRIPTION π¦
okay so here's the tea. the spigen driver gives you direct access to a slave device on the SPI bus. every single instance of a spigen device is tied to exactly one chip-select line on that bus, and every bit of I/O you do through that instance happens with that chip-select line asserted. one instance, one line, no sharing, no drama. π
now the big brain part: SPI data transfers are inherently bi-directional. there are literally not separate read and write operations. when you send commands and data to a device, data comes back from the device too β although ngl, in some cases that data may not be useful (or even documented or predictable for some devices, which is giving chaos π). same deal on a read: whatever data is sitting in the buffer at the start of the operation gets sent to the device (and typically ignored by it), and then each outgoing byte gets replaced in the buffer by the corresponding incoming byte. so yeah β every buffer you pass to the transfer functions is both an input buffer AND an output buffer. it's giving duality, it's giving main character π«
the spigen driver hands you access to the SPI slave device through these ioctl(2) calls, all defined in <sys/spigenio.h>:
π SPIGENIOC_TRANSFER (struct spigen_transfer)
transfer a command and optional associated data to/from the device, using the buffers described by the st_command and st_data fields in the spigen_transfer. set st_data.iov_len to zero if there's no data associated with the command. no data? zero. periodt.
struct spigen_transfer {
struct iovec st_command;
struct iovec st_data;
};
π SPIGENIOC_TRANSFER_MMAPPED (spigen_transfer_mmapped)
transfer a command and optional associated data to/from the device, where the buffers for the transfer are a previously-mmap'd region πΊοΈ the length of the command and the data inside that region are described by the stm_command_length and stm_data_length fields of spigen_transfer_mmapped. if stm_data_length is non-zero, the data shows up in the memory region immediately following the command β that is, at offset stm_command_length from the start of the mapped region. math is math, bestie β¨
struct spigen_transfer_mmapped {
size_t stm_command_length;
size_t stm_data_length;
};
π SPIGENIOC_GET_CLOCK_SPEED (uint32_t)
get the maximum clock speed (bus frequency in Hertz) that's gonna be used when talking to this slave device.
π SPIGENIOC_SET_CLOCK_SPEED (uint32_t)
set the maximum clock speed (bus frequency in Hertz) used when talking to this slave device. and here's the nice part: the setting stays in effect for subsequent transfers, so you do not have to reset it before every single transfer. obsessed. π«Ά one little heads up though β the actual bus frequency may end up lower because of hardware limitations of the SPI bus controller device. hardware said "I'm the captain now" π
π SPIGENIOC_GET_SPI_MODE (uint32_t)
get the SPI mode (clock polarity and phase) used when communicating with this device.
π SPIGENIOC_SET_SPI_MODE (uint32_t)
set the SPI mode (clock polarity and phase) used when communicating with this device. same glow-up as the clock speed: the setting remains in effect for subsequent transfers, so no need to reset it before each transfer. set it once, live your life π
π HINTS CONFIGURATION π
on a device.hints(5) based system (hi MIPS π), these values are configurable for spigen:
hint.spigen.%d.atβ thespibusthespigeninstance is attached to. it's giving "where do you live" πhint.spigen.%d.clockβ the maximum bus frequency to use when communicating with this device. actual bus speed may be lower, depending on what the SPI bus controller hardware can actually do.hint.spigen.%d.csβ the chip-select number to assert when performing I/O for this device. and here's the spicy bit: set the high bit (1 << 31) to invert the logic level of the chip select line. flipping the bit, flipping the script πhint.spigen.%d.modeβ the SPI mode (0-3) to use when communicating with this device.
π FDT CONFIGURATION π
on an fdt(4) based system, the spigen device is defined as a slave device subnode of the SPI bus controller node. every single property documented in the spibus.txt bindings document can be used with the spigen device β all of them, no cap. the most commonly-used ones are documented right down here π
the required ones (non-negotiable bestie)
compatibleβ must be the string"freebsd,spigen". exactly that. no typos, we're not doing that today.regβ chip select address of device.spi-max-frequencyβ the maximum bus frequency to use when communicating with this slave device. actual bus speed may be lower, depending on the capabilities of the SPI bus controller hardware. (yes, same disclaimer as before, the hardware is simply built different π)
the optional ones (nice to have, still cute)
spi-cphaβ empty property indicating the slave device requires shifted clock phase (CPHA) mode.spi-cpolβ empty property indicating the slave device requires inverse clock polarity (CPOL) mode.spi-cs-highβ empty property indicating the slave device requires chip select active high.
π FILES π
/dev/spigen*
that's the spot. that's where the magic lives β¨
π SEE ALSO π
go read those too, they're the supporting cast and they ate π
π HISTORY π
the spigen driver appeared in FreeBSD 11.0. FDT support appeared in FreeBSD 11.2. glow-up timeline fr fr β
aaaand that's the whole page bestie, you're officially a spigen girly now π
π¦
this one came to you from Debian, dated April 7, 2018 β mwah, xoxo, go assert some chip selects for me ππ
π¦ where this page comes from
- debian bookworm: freebsd-manpages 12.2-1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- debian trixie: freebsd-manpages 12.2-2 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- ubuntu jammy: freebsd-manpages 12.2-1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- ubuntu noble: freebsd-manpages 12.2-1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- ubuntu questing: freebsd-manpages 12.2-2
- ubuntu resolute: freebsd-manpages 12.2-2build1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- ubuntu stonking: freebsd-manpages 12.2-2build1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- Copyright (c) 2018 Ian Lepore <ian@freebsd.org>
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms