drivers/spi/spi-synquacer.c

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

File Facts

System
Linux kernel
Corpus path
drivers/spi/spi-synquacer.c
Extension
.c
Size
22253 bytes
Lines
822
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 synquacer_spi {
	struct device *dev;
	struct completion transfer_done;
	unsigned int cs;
	unsigned int bpw;
	unsigned int mode;
	unsigned int speed;
	bool aces, rtm;
	void *rx_buf;
	const void *tx_buf;
	struct clk *clk;
	int clk_src_type;
	void __iomem *regs;
	u32 tx_words, rx_words;
	unsigned int bus_width;
	unsigned int transfer_mode;
	char rx_irq_name[SYNQUACER_HSSPI_IRQ_NAME_MAX];
	char tx_irq_name[SYNQUACER_HSSPI_IRQ_NAME_MAX];
};

static int read_fifo(struct synquacer_spi *sspi)
{
	u32 len = readl(sspi->regs + SYNQUACER_HSSPI_REG_DMSTATUS);

	len = (len >> SYNQUACER_HSSPI_DMSTATUS_RX_DATA_SHIFT) &
	       SYNQUACER_HSSPI_DMSTATUS_RX_DATA_MASK;
	len = min(len, sspi->rx_words);

	switch (sspi->bpw) {
	case 8: {
		u8 *buf = sspi->rx_buf;

		ioread8_rep(sspi->regs + SYNQUACER_HSSPI_REG_RX_FIFO,
			    buf, len);
		sspi->rx_buf = buf + len;
		break;
	}
	case 16: {
		u16 *buf = sspi->rx_buf;

		ioread16_rep(sspi->regs + SYNQUACER_HSSPI_REG_RX_FIFO,
			     buf, len);
		sspi->rx_buf = buf + len;
		break;
	}
	case 24:
		/* fallthrough, should use 32-bits access */
	case 32: {
		u32 *buf = sspi->rx_buf;

		ioread32_rep(sspi->regs + SYNQUACER_HSSPI_REG_RX_FIFO,
			     buf, len);
		sspi->rx_buf = buf + len;
		break;
	}
	default:
		return -EINVAL;
	}

	sspi->rx_words -= len;
	return 0;
}

static int write_fifo(struct synquacer_spi *sspi)
{
	u32 len = readl(sspi->regs + SYNQUACER_HSSPI_REG_DMSTATUS);

	len = (len >> SYNQUACER_HSSPI_DMSTATUS_TX_DATA_SHIFT) &
	       SYNQUACER_HSSPI_DMSTATUS_TX_DATA_MASK;
	len = min(SYNQUACER_HSSPI_FIFO_DEPTH - len,
		    sspi->tx_words);

	switch (sspi->bpw) {
	case 8: {
		const u8 *buf = sspi->tx_buf;

		iowrite8_rep(sspi->regs + SYNQUACER_HSSPI_REG_TX_FIFO,
			     buf, len);
		sspi->tx_buf = buf + len;
		break;
	}
	case 16: {
		const u16 *buf = sspi->tx_buf;

		iowrite16_rep(sspi->regs + SYNQUACER_HSSPI_REG_TX_FIFO,
			      buf, len);
		sspi->tx_buf = buf + len;
		break;
	}
	case 24:

Annotation

Implementation Notes