drivers/i3c/master/adi-i3c-master.c

Source file repositories/reference/linux-study-clean/drivers/i3c/master/adi-i3c-master.c

File Facts

System
Linux kernel
Corpus path
drivers/i3c/master/adi-i3c-master.c
Extension
.c
Size
26443 bytes
Lines
1017
Domain
Driver Families
Bucket
drivers/i3c
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 adi_i3c_cmd {
	u32 cmd0;
	u32 cmd1;
	u32 tx_len;
	const void *tx_buf;
	u32 rx_len;
	void *rx_buf;
	u32 error;
};

struct adi_i3c_xfer {
	struct list_head node;
	struct completion comp;
	int ret;
	unsigned int ncmds;
	unsigned int ncmds_comp;
	struct adi_i3c_cmd cmds[] __counted_by(ncmds);
};

struct adi_i3c_master {
	struct i3c_master_controller base;
	u32 free_rr_slots;
	struct {
		unsigned int num_slots;
		struct i3c_dev_desc **slots;
		spinlock_t lock; /* Protect IBI slot access */
	} ibi;
	struct {
		struct list_head list;
		struct adi_i3c_xfer *cur;
		spinlock_t lock; /* Protect transfer */
	} xferqueue;
	void __iomem *regs;
	struct clk *clk;
	unsigned long i3c_scl_lim;
	struct {
		u8 addrs[ADI_MAX_DEVS];
		u8 index;
	} daa;
};

static inline struct adi_i3c_master *to_adi_i3c_master(struct i3c_master_controller *master)
{
	return container_of(master, struct adi_i3c_master, base);
}

static void adi_i3c_master_wr_to_tx_fifo(struct adi_i3c_master *master,
					 const u8 *buf, unsigned int nbytes)
{
	unsigned int n, m;

	n = readl(master->regs + REG_SDO_FIFO_ROOM);
	m = min(n, nbytes);
	i3c_writel_fifo(master->regs + REG_SDO_FIFO, buf, m);
}

static void adi_i3c_master_rd_from_rx_fifo(struct adi_i3c_master *master,
					   u8 *buf, unsigned int nbytes)
{
	i3c_readl_fifo(master->regs + REG_SDI_FIFO, buf, nbytes);
}

static bool adi_i3c_master_supports_ccc_cmd(struct i3c_master_controller *m,
					    const struct i3c_ccc_cmd *cmd)
{
	if (cmd->ndests > 1)
		return false;

	switch (cmd->id) {
	case I3C_CCC_ENEC(true):
	case I3C_CCC_ENEC(false):
	case I3C_CCC_DISEC(true):
	case I3C_CCC_DISEC(false):
	case I3C_CCC_RSTDAA(true):
	case I3C_CCC_RSTDAA(false):
	case I3C_CCC_ENTDAA:
	case I3C_CCC_SETDASA:
	case I3C_CCC_SETNEWDA:
	case I3C_CCC_GETMWL:
	case I3C_CCC_GETMRL:
	case I3C_CCC_GETPID:
	case I3C_CCC_GETBCR:
	case I3C_CCC_GETDCR:
	case I3C_CCC_GETSTATUS:
	case I3C_CCC_GETHDRCAP:
		return true;
	default:
		break;
	}

Annotation

Implementation Notes