drivers/base/regmap/regmap-spi-avmm.c

Source file repositories/reference/linux-study-clean/drivers/base/regmap/regmap-spi-avmm.c

File Facts

System
Linux kernel
Corpus path
drivers/base/regmap/regmap-spi-avmm.c
Extension
.c
Size
19585 bytes
Lines
715
Domain
Driver Families
Bucket
drivers/base
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 trans_req_header {
	u8 code;
	u8 rsvd;
	__be16 size;
	__be32 addr;
} __packed;

struct trans_resp_header {
	u8 r_code;
	u8 rsvd;
	__be16 size;
} __packed;

#define TRANS_REQ_HD_SIZE	(sizeof(struct trans_req_header))
#define TRANS_RESP_HD_SIZE	(sizeof(struct trans_resp_header))

/*
 * In transaction layer,
 * the write request format is: Transaction request header + data
 * the read request format is: Transaction request header
 * the write response format is: Transaction response header
 * the read response format is: pure data, no Transaction response header
 */
#define TRANS_WR_TX_SIZE(n)	(TRANS_REQ_HD_SIZE + SPI_AVMM_VAL_SIZE * (n))
#define TRANS_RD_TX_SIZE	TRANS_REQ_HD_SIZE
#define TRANS_TX_MAX		TRANS_WR_TX_SIZE(MAX_WRITE_CNT)

#define TRANS_RD_RX_SIZE(n)	(SPI_AVMM_VAL_SIZE * (n))
#define TRANS_WR_RX_SIZE	TRANS_RESP_HD_SIZE
#define TRANS_RX_MAX		TRANS_RD_RX_SIZE(MAX_READ_CNT)

/* tx & rx share one transaction layer buffer */
#define TRANS_BUF_SIZE		((TRANS_TX_MAX > TRANS_RX_MAX) ?	\
				 TRANS_TX_MAX : TRANS_RX_MAX)

/*
 * In tx phase, the host prepares all the phy layer bytes of a request in the
 * phy buffer and sends them in a batch.
 *
 * The packet layer and physical layer defines several special chars for
 * various purpose, when a transaction layer byte hits one of these special
 * chars, it should be escaped. The escape rule is, "Escape char first,
 * following the byte XOR'ed with 0x20".
 *
 * This macro defines the max possible length of the phy data. In the worst
 * case, all transaction layer bytes need to be escaped (so the data length
 * doubles), plus 4 special chars (SOP, CHANNEL, CHANNEL_NUM, EOP). Finally
 * we should make sure the length is aligned to SPI BPW.
 */
#define PHY_TX_MAX		ALIGN(2 * TRANS_TX_MAX + 4, 4)

/*
 * Unlike tx, phy rx is affected by possible PHY_IDLE bytes from slave, the max
 * length of the rx bit stream is unpredictable. So the driver reads the words
 * one by one, and parses each word immediately into transaction layer buffer.
 * Only one word length of phy buffer is used for rx.
 */
#define PHY_BUF_SIZE		PHY_TX_MAX

/**
 * struct spi_avmm_bridge - SPI slave to AVMM bus master bridge
 *
 * @spi: spi slave associated with this bridge.
 * @word_len: bytes of word for spi transfer.
 * @trans_len: length of valid data in trans_buf.
 * @phy_len: length of valid data in phy_buf.
 * @trans_buf: the bridge buffer for transaction layer data.
 * @phy_buf: the bridge buffer for physical layer data.
 * @swap_words: the word swapping cb for phy data. NULL if not needed.
 *
 * As a device's registers are implemented on the AVMM bus address space, it
 * requires the driver to issue formatted requests to spi slave to AVMM bus
 * master bridge to perform register access.
 */
struct spi_avmm_bridge {
	struct spi_device *spi;
	unsigned char word_len;
	unsigned int trans_len;
	unsigned int phy_len;
	/* bridge buffer used in translation between protocol layers */
	char trans_buf[TRANS_BUF_SIZE];
	char phy_buf[PHY_BUF_SIZE];
	void (*swap_words)(void *buf, unsigned int len);
};

static void br_swap_words_32(void *buf, unsigned int len)
{
	swab32_array(buf, len / 4);
}

Annotation

Implementation Notes