drivers/spi/spi-lantiq-ssc.c

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

File Facts

System
Linux kernel
Corpus path
drivers/spi/spi-lantiq-ssc.c
Extension
.c
Size
27788 bytes
Lines
1038
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 lantiq_ssc_hwcfg {
	int (*cfg_irq)(struct platform_device *pdev, struct lantiq_ssc_spi *spi);
	unsigned int	irnen_r;
	unsigned int	irnen_t;
	unsigned int	irncr;
	unsigned int	irnicr;
	bool		irq_ack;
	u32		fifo_size_mask;
};

struct lantiq_ssc_spi {
	struct spi_controller		*host;
	struct device			*dev;
	void __iomem			*regbase;
	struct clk			*spi_clk;
	struct clk			*fpi_clk;
	const struct lantiq_ssc_hwcfg	*hwcfg;

	spinlock_t			lock;
	struct workqueue_struct		*wq;
	struct work_struct		work;

	const u8			*tx;
	u8				*rx;
	unsigned int			tx_todo;
	unsigned int			rx_todo;
	unsigned int			bits_per_word;
	unsigned int			speed_hz;
	unsigned int			tx_fifo_size;
	unsigned int			rx_fifo_size;
	unsigned int			base_cs;
	unsigned int			fdx_tx_level;
};

static u32 lantiq_ssc_readl(const struct lantiq_ssc_spi *spi, u32 reg)
{
	return __raw_readl(spi->regbase + reg);
}

static void lantiq_ssc_writel(const struct lantiq_ssc_spi *spi, u32 val,
			      u32 reg)
{
	__raw_writel(val, spi->regbase + reg);
}

static void lantiq_ssc_maskl(const struct lantiq_ssc_spi *spi, u32 clr,
			     u32 set, u32 reg)
{
	u32 val = __raw_readl(spi->regbase + reg);

	val &= ~clr;
	val |= set;
	__raw_writel(val, spi->regbase + reg);
}

static unsigned int tx_fifo_level(const struct lantiq_ssc_spi *spi)
{
	const struct lantiq_ssc_hwcfg *hwcfg = spi->hwcfg;
	u32 fstat = lantiq_ssc_readl(spi, LTQ_SPI_FSTAT);

	return (fstat >> LTQ_SPI_FSTAT_TXFFL_S) & hwcfg->fifo_size_mask;
}

static unsigned int rx_fifo_level(const struct lantiq_ssc_spi *spi)
{
	const struct lantiq_ssc_hwcfg *hwcfg = spi->hwcfg;
	u32 fstat = lantiq_ssc_readl(spi, LTQ_SPI_FSTAT);

	return (fstat >> LTQ_SPI_FSTAT_RXFFL_S) & hwcfg->fifo_size_mask;
}

static unsigned int tx_fifo_free(const struct lantiq_ssc_spi *spi)
{
	return spi->tx_fifo_size - tx_fifo_level(spi);
}

static void rx_fifo_reset(const struct lantiq_ssc_spi *spi)
{
	u32 val = spi->rx_fifo_size << LTQ_SPI_RXFCON_RXFITL_S;

	val |= LTQ_SPI_RXFCON_RXFEN | LTQ_SPI_RXFCON_RXFLU;
	lantiq_ssc_writel(spi, val, LTQ_SPI_RXFCON);
}

static void tx_fifo_reset(const struct lantiq_ssc_spi *spi)
{
	u32 val = 1 << LTQ_SPI_TXFCON_TXFITL_S;

	val |= LTQ_SPI_TXFCON_TXFEN | LTQ_SPI_TXFCON_TXFLU;
	lantiq_ssc_writel(spi, val, LTQ_SPI_TXFCON);

Annotation

Implementation Notes