drivers/spi/spi-slave-mt27xx.c

Source file repositories/reference/linux-study-clean/drivers/spi/spi-slave-mt27xx.c

File Facts

System
Linux kernel
Corpus path
drivers/spi/spi-slave-mt27xx.c
Extension
.c
Size
13824 bytes
Lines
562
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 mtk_spi_slave {
	struct device *dev;
	void __iomem *base;
	struct clk *spi_clk;
	struct completion xfer_done;
	struct spi_transfer *cur_transfer;
	bool target_aborted;
	const struct mtk_spi_compatible *dev_comp;
};

struct mtk_spi_compatible {
	const u32 max_fifo_size;
	bool must_rx;
};

static const struct mtk_spi_compatible mt2712_compat = {
	.max_fifo_size = 512,
};
static const struct mtk_spi_compatible mt8195_compat = {
	.max_fifo_size = 128,
	.must_rx = true,
};

static const struct of_device_id mtk_spi_slave_of_match[] = {
	{ .compatible = "mediatek,mt2712-spi-slave",
	  .data = (void *)&mt2712_compat,},
	{ .compatible = "mediatek,mt8195-spi-slave",
	  .data = (void *)&mt8195_compat,},
	{}
};
MODULE_DEVICE_TABLE(of, mtk_spi_slave_of_match);

static void mtk_spi_slave_disable_dma(struct mtk_spi_slave *mdata)
{
	u32 reg_val;

	reg_val = readl(mdata->base + SPIS_DMA_CFG_REG);
	reg_val &= ~RX_DMA_EN;
	reg_val &= ~TX_DMA_EN;
	writel(reg_val, mdata->base + SPIS_DMA_CFG_REG);
}

static void mtk_spi_slave_disable_xfer(struct mtk_spi_slave *mdata)
{
	u32 reg_val;

	reg_val = readl(mdata->base + SPIS_CFG_REG);
	reg_val &= ~SPIS_TX_EN;
	reg_val &= ~SPIS_RX_EN;
	writel(reg_val, mdata->base + SPIS_CFG_REG);
}

static int mtk_spi_slave_wait_for_completion(struct mtk_spi_slave *mdata)
{
	if (wait_for_completion_interruptible(&mdata->xfer_done) ||
	    mdata->target_aborted) {
		dev_err(mdata->dev, "interrupted\n");
		return -EINTR;
	}

	return 0;
}

static int mtk_spi_slave_prepare_message(struct spi_controller *ctlr,
					 struct spi_message *msg)
{
	struct mtk_spi_slave *mdata = spi_controller_get_devdata(ctlr);
	struct spi_device *spi = msg->spi;
	bool cpha, cpol;
	u32 reg_val;

	cpha = spi->mode & SPI_CPHA ? 1 : 0;
	cpol = spi->mode & SPI_CPOL ? 1 : 0;

	reg_val = readl(mdata->base + SPIS_CFG_REG);
	if (cpha)
		reg_val |= SPIS_CPHA;
	else
		reg_val &= ~SPIS_CPHA;
	if (cpol)
		reg_val |= SPIS_CPOL;
	else
		reg_val &= ~SPIS_CPOL;

	if (spi->mode & SPI_LSB_FIRST)
		reg_val &= ~(SPIS_TXMSBF | SPIS_RXMSBF);
	else
		reg_val |= SPIS_TXMSBF | SPIS_RXMSBF;

	reg_val &= ~SPIS_TX_ENDIAN;

Annotation

Implementation Notes