drivers/regulator/rtmv20-regulator.c

Source file repositories/reference/linux-study-clean/drivers/regulator/rtmv20-regulator.c

File Facts

System
Linux kernel
Corpus path
drivers/regulator/rtmv20-regulator.c
Extension
.c
Size
11760 bytes
Lines
439
Domain
Driver Families
Bucket
drivers/regulator
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 rtmv20_priv {
	struct device *dev;
	struct regmap *regmap;
	struct gpio_desc *enable_gpio;
	struct regulator_dev *rdev;
};

static int rtmv20_lsw_enable(struct regulator_dev *rdev)
{
	struct rtmv20_priv *priv = rdev_get_drvdata(rdev);
	int ret;

	gpiod_set_value(priv->enable_gpio, 1);

	/* Wait for I2C can be accessed */
	usleep_range(RTMV20_I2CRDY_TIMEUS, RTMV20_I2CRDY_TIMEUS + 100);

	/* HW re-enable, disable cache only and sync regcache here */
	regcache_cache_only(priv->regmap, false);
	ret = regcache_sync(priv->regmap);
	if (ret)
		return ret;

	return regulator_enable_regmap(rdev);
}

static int rtmv20_lsw_disable(struct regulator_dev *rdev)
{
	struct rtmv20_priv *priv = rdev_get_drvdata(rdev);
	int ret;

	ret = regulator_disable_regmap(rdev);
	if (ret)
		return ret;

	/* Mark the regcache as dirty and cache only before HW disabled */
	regcache_cache_only(priv->regmap, true);
	regcache_mark_dirty(priv->regmap);

	gpiod_set_value(priv->enable_gpio, 0);

	return 0;
}

static int rtmv20_lsw_set_current_limit(struct regulator_dev *rdev, int min_uA,
					int max_uA)
{
	int sel;

	if (min_uA > RTMV20_LSW_MAXUA || max_uA < RTMV20_LSW_MINUA)
		return -EINVAL;

	if (max_uA > RTMV20_LSW_MAXUA)
		max_uA = RTMV20_LSW_MAXUA;

	sel = (max_uA - RTMV20_LSW_MINUA) / RTMV20_LSW_STEPUA;

	/* Ensure the selected setting is still in range */
	if ((sel * RTMV20_LSW_STEPUA + RTMV20_LSW_MINUA) < min_uA)
		return -EINVAL;

	sel <<= ffs(rdev->desc->csel_mask) - 1;

	return regmap_update_bits(rdev->regmap, rdev->desc->csel_reg,
				  rdev->desc->csel_mask, sel);
}

static int rtmv20_lsw_get_current_limit(struct regulator_dev *rdev)
{
	unsigned int val;
	int ret;

	ret = regmap_read(rdev->regmap, rdev->desc->csel_reg, &val);
	if (ret)
		return ret;

	val &= rdev->desc->csel_mask;
	val >>= ffs(rdev->desc->csel_mask) - 1;

	return val * RTMV20_LSW_STEPUA + RTMV20_LSW_MINUA;
}

static const struct regulator_ops rtmv20_regulator_ops = {
	.set_current_limit = rtmv20_lsw_set_current_limit,
	.get_current_limit = rtmv20_lsw_get_current_limit,
	.enable = rtmv20_lsw_enable,
	.disable = rtmv20_lsw_disable,
	.is_enabled = regulator_is_enabled_regmap,
};

Annotation

Implementation Notes