STRUCT SPI_DEVICE(9)
π struct spi_device(9) π
okay bestie, buckle up β this is the struct spi_device page from the Kernel API Manual (yes, struct spi_device(9), we're in kernel-doc land now π) and honestly? she's iconic. this is the controller side proxy for an SPI target device β the little struct that stands between your CPU and that one random chip on your board. iykyk. β¨
π¦ SYNOPSIS π¦
struct spi_device {
struct device dev;
struct spi_controller *controller;
u32 max_speed_hz;
u8 bits_per_word;
bool rt;
#define SPI_NO_TX BIT(31) ;
#define SPI_NO_RX BIT(30) ;
#define SPI_TPM_HW_FLOW BIT(29) ;
#define SPI_MODE_KERNEL_MASK (~(BIT(29) - 1));
u32 mode;
int irq;
void *controller_state;
void *controller_data;
char modalias[SPI_NAME_SIZE];
struct spi_statistics __percpu *pcpu_statistics;
struct spi_delay word_delay;
struct spi_delay cs_setup;
struct spi_delay cs_hold;
struct spi_delay cs_inactive;
u8 chip_select[SPI_DEVICE_CS_CNT_MAX];
u8 num_chipselect;
u32 cs_index_mask : SPI_DEVICE_CS_CNT_MAX;
struct gpio_desc *cs_gpiod[SPI_DEVICE_CS_CNT_MAX];
u8 tx_lane_map[SPI_DEVICE_DATA_LANE_CNT_MAX];
u8 num_tx_lanes;
u8 rx_lane_map[SPI_DEVICE_DATA_LANE_CNT_MAX];
u8 num_rx_lanes;
#if IS_ENABLED(CONFIG_SPI_DYNAMIC);
struct list_head userspace_node;
#endif;
};
literally just look at her. gorgeous. no notes. π
πΈ Members πΈ
devβ the driver model representation of the device. her official government name. π«Άcontrollerβ the SPI controller this device is hanging out with.max_speed_hzβ the maximum clock rate to be used with this chip (on this board) β and yes, the device's driver can change it later. also,spi_transfer.speed_hzcan override this for each individual transfer. so she's flexible πbits_per_wordβ so data transfers involve one or more words, and word sizes like eight or 12 bits are common. but plot twist: in-memory wordsizes are powers of two bytes (e.g. 20 bit samples use 32 bits β the way that works is genuinely so cool). the device's driver may change this, or you can leave it at the default (0), which means protocol words are eight bit bytes. andspi_transfer.bits_per_wordcan override this for each transfer too. override queen. πrtβ makes the pump thread real time priority. real time. she's got main character energy scheduling-wise. π₯modeβ the spi mode defines how data is clocked out and in. the device's driver may change this. the "active low" default for chipselect mode can be overridden (by specifyingSPI_CS_HIGH), and so can the "MSB first" default for each word in a transfer (by specifyingSPI_LSB_FIRST). defaults are cute but options are cuter β¨irqβ negative, or the number passed torequest_irqto receive interrupts from this device.controller_stateβ the controller's runtime state.controller_dataβ board-specific definitions for the controller, like FIFO initialization parameters β¨ fr fr board-specific β¨ β comes fromboard_info.controller_data.modaliasβ the name of the driver to use with this device, or an alias for that name. this shows up in the sysfs"modalias"attribute for driver coldplugging, and in uevents used for hotplugging. she's everywhere, she's booked and busy πpcpu_statisticsβ statistics for thespi_device.word_delayβ delay to be inserted between consecutive words of a transfer.cs_setupβ delay to be introduced by the controller after CS is asserted.cs_holdβ delay to be introduced by the controller before CS is deasserted.cs_inactiveβ delay to be introduced by the controller after CS is deasserted. β οΈ and heads up: ifcs_change_delayis used fromspi_transfer, then the two delays will be added up. math is mathing πchip_selectβ array of physical chipselect;spi->chipselect[i]gives the corresponding physical CS for logical CSi. indexing, but make it hardware πnum_chipselectβ number of physical chipselects used.cs_index_maskβ bit mask of the active chipselect(s) in the chipselect array.cs_gpiodβ array of GPIO descriptors of the corresponding chipselect lines (optional,NULLwhen not using a GPIO line). no cap, she can be null. πtx_lane_mapβ map of peripheral lanes (index) to controller lanes (value).num_tx_lanesβ number of transmit lanes wired up.rx_lane_mapβ map of peripheral lanes (index) to controller lanes (value). yes bestie, same description as tx, she's symmetrical like that π¦num_rx_lanesβ number of receive lanes wired up.userspace_nodeβ entry on the parent controller'suserspace_clientslist when this device was instantiated via the sysfsnew_deviceinterface. only exists under#if IS_ENABLED(CONFIG_SPI_DYNAMIC)β conditional icon π
β¨ Description β¨
so a spi_device is used to interchange data between an SPI target device (usually a discrete chip β like, a literal physical chip on your board) and CPU memory. that's the whole job. that's the vibe check. π
inside dev, the platform_data is used to hold information about this device that's meaningful to the device's protocol driver, but not to its controller. one example might be an identifier for a chip variant with slightly different functionality; another might be information about how this particular board wires the chip's pins. it's giving "context that only matters to the diva who's actually driving." π
π₯ SEE ALSO π₯
kernel file ./include/linux/spi/spi.h, plus the whole friend group: struct spi_statistics(9), struct spi_delay(9), struct spi_driver(9), spi_unregister_driver(9), module_spi_driver(9), struct spi_controller(9), struct spi_res(9), struct spi_transfer(9), struct spi_message(9), spi_message_init_with_transfers(9), spi_is_bpw_supported(9), spi_bpw_to_bytes(9), spi_controller_xfer_timeout(9), struct spi_replaced_transfers(9), spi_sync_transfer(9), spi_write(9), spi_read(9), spi_w8r8(9), spi_w8r16(9), spi_w8r16be(9), struct spi_board_info(9) β bestie really said "you will read the whole squad." π«Ά
that's the page fr fr π this beauty lives over in ./include/linux/spi and she's dated October 2026 β struct spi_device(9), slay, go forth and talk to your chips β¨ππ¦
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms