drivers/mmc/host/wmt-sdmmc.c

Source file repositories/reference/linux-study-clean/drivers/mmc/host/wmt-sdmmc.c

File Facts

System
Linux kernel
Corpus path
drivers/mmc/host/wmt-sdmmc.c
Extension
.c
Size
24237 bytes
Lines
984
Domain
Driver Families
Bucket
drivers/mmc
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 wmt_dma_descriptor {
	u32 flags;
	u32 data_buffer_addr;
	u32 branch_addr;
	u32 reserved1;
};

struct wmt_mci_caps {
	unsigned int	f_min;
	unsigned int	f_max;
	u32		ocr_avail;
	u32		caps;
	u32		max_seg_size;
	u32		max_segs;
	u32		max_blk_size;
};

struct wmt_mci_priv {
	struct mmc_host *mmc;
	void __iomem *sdmmc_base;

	int irq_regular;
	int irq_dma;

	void *dma_desc_buffer;
	dma_addr_t dma_desc_device_addr;

	struct completion cmdcomp;
	struct completion datacomp;

	struct completion *comp_cmd;
	struct completion *comp_dma;

	struct mmc_request *req;
	struct mmc_command *cmd;

	struct clk *clk_sdmmc;
	struct device *dev;

	u8 power_inverted;
	u8 cd_inverted;
};

static void wmt_set_sd_power(struct wmt_mci_priv *priv, int enable)
{
	u32 reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE);

	if (enable ^ priv->power_inverted)
		reg_tmp &= ~BM_SD_OFF;
	else
		reg_tmp |= BM_SD_OFF;

	writeb(reg_tmp, priv->sdmmc_base + SDMMC_BUSMODE);
}

static void wmt_mci_read_response(struct mmc_host *mmc)
{
	struct wmt_mci_priv *priv;
	int idx1, idx2;
	u8 tmp_resp;
	u32 response;

	priv = mmc_priv(mmc);

	for (idx1 = 0; idx1 < 4; idx1++) {
		response = 0;
		for (idx2 = 0; idx2 < 4; idx2++) {
			if ((idx1 == 3) && (idx2 == 3))
				tmp_resp = readb(priv->sdmmc_base + SDMMC_RSP);
			else
				tmp_resp = readb(priv->sdmmc_base + SDMMC_RSP +
						 (idx1*4) + idx2 + 1);
			response |= (tmp_resp << (idx2 * 8));
		}
		priv->cmd->resp[idx1] = cpu_to_be32(response);
	}
}

static void wmt_mci_start_command(struct wmt_mci_priv *priv)
{
	u32 reg_tmp;

	reg_tmp = readb(priv->sdmmc_base + SDMMC_CTLR);
	writeb(reg_tmp | CTLR_CMD_START, priv->sdmmc_base + SDMMC_CTLR);
}

static int wmt_mci_send_command(struct mmc_host *mmc, u8 command, u8 cmdtype,
				u32 arg, u8 rsptype)
{
	struct wmt_mci_priv *priv;

Annotation

Implementation Notes