drivers/base/regmap/regmap-sdw-mbq.c

Source file repositories/reference/linux-study-clean/drivers/base/regmap/regmap-sdw-mbq.c

File Facts

System
Linux kernel
Corpus path
drivers/base/regmap/regmap-sdw-mbq.c
Extension
.c
Size
6904 bytes
Lines
279
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 regmap_mbq_context {
	struct device *dev;
	struct sdw_slave *sdw;

	bool (*readable_reg)(struct device *dev, unsigned int reg);

	struct regmap_sdw_mbq_cfg cfg;

	int val_size;
};

static int regmap_sdw_mbq_size(struct regmap_mbq_context *ctx, unsigned int reg)
{
	int size = ctx->val_size;

	if (ctx->cfg.mbq_size) {
		size = ctx->cfg.mbq_size(ctx->dev, reg);
		if (!size || size > ctx->val_size)
			return -EINVAL;
	}

	return size;
}

static bool regmap_sdw_mbq_deferrable(struct regmap_mbq_context *ctx, unsigned int reg)
{
	if (ctx->cfg.deferrable)
		return ctx->cfg.deferrable(ctx->dev, reg);

	return false;
}

static int regmap_sdw_mbq_poll_busy(struct sdw_slave *slave, unsigned int reg,
				    struct regmap_mbq_context *ctx)
{
	struct device *dev = ctx->dev;
	int val, ret = 0;

	dev_dbg(dev, "Deferring transaction for 0x%x\n", reg);

	reg = SDW_SDCA_CTL(SDW_SDCA_CTL_FUNC(reg), 0,
			   SDCA_CTL_ENTITY_0_FUNCTION_STATUS, 0);

	if (ctx->readable_reg(dev, reg)) {
		ret = read_poll_timeout(sdw_read_no_pm, val,
					val < 0 || !(val & SDCA_CTL_ENTITY_0_FUNCTION_BUSY),
					ctx->cfg.timeout_us, ctx->cfg.retry_us,
					false, slave, reg);
		if (val < 0)
			return val;
		if (ret)
			dev_err(dev, "Function busy timed out 0x%x: %d\n", reg, val);
	} else {
		fsleep(ctx->cfg.timeout_us);
	}

	return ret;
}

static int regmap_sdw_mbq_write_impl(struct sdw_slave *slave,
				     unsigned int reg, unsigned int val,
				     int mbq_size)
{
	int shift = mbq_size * BITS_PER_BYTE;
	int ret;

	while (--mbq_size > 0) {
		shift -= BITS_PER_BYTE;

		ret = sdw_write_no_pm(slave, SDW_SDCA_MBQ_CTL(reg),
				      (val >> shift) & 0xff);
		if (ret < 0)
			return ret;
	}

	return sdw_write_no_pm(slave, reg, val & 0xff);
}

static int regmap_sdw_mbq_write(void *context, unsigned int reg, unsigned int val)
{
	struct regmap_mbq_context *ctx = context;
	struct sdw_slave *slave = ctx->sdw;
	struct device *dev = ctx->dev;
	bool deferrable = regmap_sdw_mbq_deferrable(ctx, reg);
	int mbq_size = regmap_sdw_mbq_size(ctx, reg);
	int ret;

	if (mbq_size < 0)
		return mbq_size;

Annotation

Implementation Notes