drivers/spi/spi-fsl-lpspi.c

Source file repositories/reference/linux-study-clean/drivers/spi/spi-fsl-lpspi.c

File Facts

System
Linux kernel
Corpus path
drivers/spi/spi-fsl-lpspi.c
Extension
.c
Size
26937 bytes
Lines
1078
Domain
Driver Families
Bucket
drivers/spi
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct fsl_lpspi_devtype_data {
	u8 prescale_max : 3; /* 0 == no limit */
	bool query_hw_for_num_cs : 1;
};

struct lpspi_config {
	u8 bpw;
	u8 chip_select;
	u8 prescale;
	u32 mode;
	u32 speed_hz;
	u32 effective_speed_hz;
};

struct fsl_lpspi_data {
	struct device *dev;
	void __iomem *base;
	unsigned long base_phys;
	struct clk *clk_ipg;
	struct clk *clk_per;
	bool is_target;
	bool is_only_cs1;
	bool is_first_byte;

	void *rx_buf;
	const void *tx_buf;
	void (*tx)(struct fsl_lpspi_data *fsl_lpspi);
	void (*rx)(struct fsl_lpspi_data *fsl_lpspi);

	u32 remain;
	u8 watermark;
	u8 txfifosize;
	u8 rxfifosize;

	struct lpspi_config config;
	struct completion xfer_done;

	bool target_aborted;

	/* DMA */
	bool usedma;
	struct completion dma_rx_completion;
	struct completion dma_tx_completion;

	const struct fsl_lpspi_devtype_data *devtype_data;
};

/*
 * Devices with ERR051608 have a max TCR_PRESCALE value of 1, otherwise there is
 * no prescale limit: https://www.nxp.com/docs/en/errata/i.MX93_1P87f.pdf
 */
static const struct fsl_lpspi_devtype_data imx93_lpspi_devtype_data = {
	.prescale_max = 1,
	.query_hw_for_num_cs = true,
};

static const struct fsl_lpspi_devtype_data imx7ulp_lpspi_devtype_data = {
	/* All defaults */
};

static const struct fsl_lpspi_devtype_data s32g_lpspi_devtype_data = {
	.query_hw_for_num_cs = true,
};

static const struct of_device_id fsl_lpspi_dt_ids[] = {
	{ .compatible = "fsl,imx7ulp-spi", .data = &imx7ulp_lpspi_devtype_data,},
	{ .compatible = "fsl,imx93-spi", .data = &imx93_lpspi_devtype_data,},
	{ .compatible = "nxp,s32g2-lpspi", .data = &s32g_lpspi_devtype_data,},
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, fsl_lpspi_dt_ids);

#define LPSPI_BUF_RX(type)						\
static void fsl_lpspi_buf_rx_##type(struct fsl_lpspi_data *fsl_lpspi)	\
{									\
	unsigned int val = readl(fsl_lpspi->base + IMX7ULP_RDR);	\
									\
	if (fsl_lpspi->rx_buf) {					\
		*(type *)fsl_lpspi->rx_buf = val;			\
		fsl_lpspi->rx_buf += sizeof(type);                      \
	}								\
}

#define LPSPI_BUF_TX(type)						\
static void fsl_lpspi_buf_tx_##type(struct fsl_lpspi_data *fsl_lpspi)	\
{									\
	type val = 0;							\
									\
	if (fsl_lpspi->tx_buf) {					\
		val = *(type *)fsl_lpspi->tx_buf;			\

Annotation

Implementation Notes