drivers/spi/spi-aspeed-smc.c

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

File Facts

System
Linux kernel
Corpus path
drivers/spi/spi-aspeed-smc.c
Extension
.c
Size
45869 bytes
Lines
1734
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 aspeed_spi_chip {
	struct aspeed_spi	*aspi;
	u32			 cs;
	void __iomem		*ctl;
	void __iomem		*ahb_base;
	u32			 ahb_window_size;
	u32			 ctl_val[ASPEED_SPI_MAX];
	u32			 clk_freq;
	bool			 force_user_mode;
};

struct aspeed_spi_data {
	u32	ctl0;
	u32	max_cs;
	bool	hastype;
	u32	mode_bits;
	u32	we0;
	u32	timing;
	u32	hclk_mask;
	u32	hdiv_max;
	u32	min_window_size;
	bool	full_duplex;

	phys_addr_t (*segment_start)(struct aspeed_spi *aspi, u32 reg);
	phys_addr_t (*segment_end)(struct aspeed_spi *aspi, u32 reg);
	u32 (*segment_reg)(struct aspeed_spi *aspi, phys_addr_t start,
			   phys_addr_t end);
	int (*adjust_window)(struct aspeed_spi *aspi);
	u32 (*get_clk_div)(struct aspeed_spi_chip *chip, u32 hz);
	int (*calibrate)(struct aspeed_spi_chip *chip, u32 hdiv,
			 const u8 *golden_buf, u8 *test_buf);
};

#define ASPEED_SPI_MAX_NUM_CS	5

struct aspeed_spi {
	const struct aspeed_spi_data	*data;

	void __iomem		*regs;
	phys_addr_t		 ahb_base_phy;
	u32			 ahb_window_size;
	u32			 num_cs;
	struct device		*dev;

	struct clk		*clk;
	u32			 clk_freq;
	u8			 cs_change;

	struct aspeed_spi_chip	 chips[ASPEED_SPI_MAX_NUM_CS];
};

static u32 aspeed_spi_get_io_mode(const struct spi_mem_op *op)
{
	switch (op->data.buswidth) {
	case 1:
		return CTRL_IO_SINGLE_DATA;
	case 2:
		return CTRL_IO_DUAL_DATA;
	case 4:
		return CTRL_IO_QUAD_DATA;
	default:
		return CTRL_IO_SINGLE_DATA;
	}
}

static void aspeed_spi_set_io_mode(struct aspeed_spi_chip *chip, u32 io_mode)
{
	u32 ctl;

	if (io_mode > 0) {
		ctl = readl(chip->ctl) & ~CTRL_IO_MODE_MASK;
		ctl |= io_mode;
		writel(ctl, chip->ctl);
	}
}

static void aspeed_spi_start_user(struct aspeed_spi_chip *chip)
{
	u32 ctl = chip->ctl_val[ASPEED_SPI_BASE];

	ctl |= CTRL_IO_MODE_USER | CTRL_CE_STOP_ACTIVE;
	writel(ctl, chip->ctl);

	ctl &= ~CTRL_CE_STOP_ACTIVE;
	writel(ctl, chip->ctl);
}

static void aspeed_spi_stop_user(struct aspeed_spi_chip *chip)
{
	u32 ctl = chip->ctl_val[ASPEED_SPI_READ] |

Annotation

Implementation Notes