drivers/spi/spi-microchip-core-spi.c

Source file repositories/reference/linux-study-clean/drivers/spi/spi-microchip-core-spi.c

File Facts

System
Linux kernel
Corpus path
drivers/spi/spi-microchip-core-spi.c
Extension
.c
Size
12301 bytes
Lines
432
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 mchp_corespi {
	void __iomem *regs;
	struct clk *clk;
	const u8 *tx_buf;
	u8 *rx_buf;
	u32 clk_gen;
	int irq;
	unsigned int tx_len;
	unsigned int rx_len;
	u32 fifo_depth;
};

static inline void mchp_corespi_disable(struct mchp_corespi *spi)
{
	u8 control = readb(spi->regs + MCHP_CORESPI_REG_CONTROL);

	control &= ~MCHP_CORESPI_CONTROL_ENABLE;

	writeb(control, spi->regs + MCHP_CORESPI_REG_CONTROL);
}

static inline void mchp_corespi_read_fifo(struct mchp_corespi *spi, u32 fifo_max)
{
	for (int i = 0; i < fifo_max; i++) {
		u32 data;

		while (readb(spi->regs + MCHP_CORESPI_REG_STAT) &
		       MCHP_CORESPI_STATUS_RXFIFO_EMPTY)
			;

		/* On TX-only transfers always perform a dummy read */
		data = readb(spi->regs + MCHP_CORESPI_REG_RXDATA);
		if (spi->rx_buf)
			*spi->rx_buf++ = data;

		spi->rx_len--;
	}
}

static void mchp_corespi_enable_ints(struct mchp_corespi *spi)
{
	u8 control = readb(spi->regs + MCHP_CORESPI_REG_CONTROL);

	control |= INT_ENABLE_MASK;
	writeb(control, spi->regs + MCHP_CORESPI_REG_CONTROL);
}

static void mchp_corespi_disable_ints(struct mchp_corespi *spi)
{
	u8 control = readb(spi->regs + MCHP_CORESPI_REG_CONTROL);

	control &= ~INT_ENABLE_MASK;
	writeb(control, spi->regs + MCHP_CORESPI_REG_CONTROL);
}

static inline void mchp_corespi_write_fifo(struct mchp_corespi *spi, u32 fifo_max)
{
	for (int i = 0; i < fifo_max; i++) {
		if (readb(spi->regs + MCHP_CORESPI_REG_STAT) &
		    MCHP_CORESPI_STATUS_TXFIFO_FULL)
			break;

		/* On RX-only transfers always perform a dummy write */
		if (spi->tx_buf)
			writeb(*spi->tx_buf++, spi->regs + MCHP_CORESPI_REG_TXDATA);
		else
			writeb(0xaa, spi->regs + MCHP_CORESPI_REG_TXDATA);

		spi->tx_len--;
	}
}

static void mchp_corespi_set_cs(struct spi_device *spi, bool disable)
{
	struct mchp_corespi *corespi = spi_controller_get_devdata(spi->controller);
	u32 reg;

	reg = readb(corespi->regs + MCHP_CORESPI_REG_SSEL);
	reg &= ~BIT(spi_get_chipselect(spi, 0));
	reg |= !disable << spi_get_chipselect(spi, 0);

	writeb(reg, corespi->regs + MCHP_CORESPI_REG_SSEL);
}

static int mchp_corespi_setup(struct spi_device *spi)
{
	if (spi_get_csgpiod(spi, 0))
		return 0;

	if (spi->mode & (SPI_CS_HIGH)) {

Annotation

Implementation Notes