drivers/spi/spi-fsi.c

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

File Facts

System
Linux kernel
Corpus path
drivers/spi/spi-fsi.c
Extension
.c
Size
14034 bytes
Lines
603
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 fsi2spi {
	struct fsi_device *fsi; /* FSI2SPI CFAM engine device */
	struct mutex lock; /* lock access to the device */
};

struct fsi_spi {
	struct device *dev;	/* SPI controller device */
	struct fsi2spi *bridge; /* FSI2SPI device */
	u32 base;
};

struct fsi_spi_sequence {
	int bit;
	u64 data;
};

static int fsi_spi_check_mux(struct fsi_device *fsi, struct device *dev)
{
	int rc;
	u32 root_ctrl_8;
	__be32 root_ctrl_8_be;

	rc = fsi_slave_read(fsi->slave, FSI_MBOX_ROOT_CTRL_8, &root_ctrl_8_be,
			    sizeof(root_ctrl_8_be));
	if (rc)
		return rc;

	root_ctrl_8 = be32_to_cpu(root_ctrl_8_be);
	dev_dbg(dev, "Root control register 8: %08x\n", root_ctrl_8);
	if ((root_ctrl_8 & FSI_MBOX_ROOT_CTRL_8_SPI_MUX) ==
	     FSI_MBOX_ROOT_CTRL_8_SPI_MUX)
		return 0;

	return -ENOLINK;
}

static int fsi_spi_check_status(struct fsi_spi *ctx)
{
	int rc;
	u32 sts;
	__be32 sts_be;

	rc = fsi_device_read(ctx->bridge->fsi, FSI2SPI_STATUS, &sts_be,
			     sizeof(sts_be));
	if (rc)
		return rc;

	sts = be32_to_cpu(sts_be);
	if (sts & FSI2SPI_STATUS_ANY_ERROR) {
		dev_err(ctx->dev, "Error with FSI2SPI interface: %08x.\n", sts);
		return -EIO;
	}

	return 0;
}

static int fsi_spi_read_reg(struct fsi_spi *ctx, u32 offset, u64 *value)
{
	int rc = 0;
	__be32 cmd_be;
	__be32 data_be;
	u32 cmd = offset + ctx->base;
	struct fsi2spi *bridge = ctx->bridge;

	*value = 0ULL;

	if (cmd & FSI2SPI_CMD_WRITE)
		return -EINVAL;

	rc = mutex_lock_interruptible(&bridge->lock);
	if (rc)
		return rc;

	cmd_be = cpu_to_be32(cmd);
	rc = fsi_device_write(bridge->fsi, FSI2SPI_CMD, &cmd_be,
			      sizeof(cmd_be));
	if (rc)
		goto unlock;

	rc = fsi_spi_check_status(ctx);
	if (rc)
		goto unlock;

	rc = fsi_device_read(bridge->fsi, FSI2SPI_DATA0, &data_be,
			     sizeof(data_be));
	if (rc)
		goto unlock;

	*value |= (u64)be32_to_cpu(data_be) << 32;

Annotation

Implementation Notes