drivers/regulator/rtq2208-regulator.c

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

File Facts

System
Linux kernel
Corpus path
drivers/regulator/rtq2208-regulator.c
Extension
.c
Size
19882 bytes
Lines
669
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 rtq2208_regulator_desc {
	struct regulator_desc desc;
	unsigned int mtp_sel_reg;
	unsigned int mtp_sel_mask;
	unsigned int mode_reg;
	unsigned int mode_mask;
	unsigned int suspend_config_reg;
	unsigned int suspend_enable_mask;
	unsigned int suspend_mode_mask;
};

struct rtq2208_rdev_map {
	struct regulator_dev *rdev[RTQ2208_LDO_MAX];
	struct regmap *regmap;
	struct device *dev;
};

/* set Normal Auto/FCCM mode */
static int rtq2208_set_mode(struct regulator_dev *rdev, unsigned int mode)
{
	const struct rtq2208_regulator_desc *rdesc =
		(const struct rtq2208_regulator_desc *)rdev->desc;
	unsigned int val, shift;

	switch (mode) {
	case REGULATOR_MODE_NORMAL:
		val = RTQ2208_AUTO_MODE;
		break;
	case REGULATOR_MODE_FAST:
		val = RTQ2208_FCCM;
		break;
	default:
		return -EINVAL;
	}

	shift = ffs(rdesc->mode_mask) - 1;
	return regmap_update_bits(rdev->regmap, rdesc->mode_reg,
				  rdesc->mode_mask, val << shift);
}

static unsigned int rtq2208_get_mode(struct regulator_dev *rdev)
{
	const struct rtq2208_regulator_desc *rdesc =
		(const struct rtq2208_regulator_desc *)rdev->desc;
	unsigned int mode_val;
	int ret;

	ret = regmap_read(rdev->regmap, rdesc->mode_reg, &mode_val);
	if (ret)
		return REGULATOR_MODE_INVALID;

	return (mode_val & rdesc->mode_mask) ? REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL;
}

static int rtq2208_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
{
	const struct regulator_desc *desc = rdev->desc;
	unsigned int sel = 0, val;

	ramp_delay = max(ramp_delay, RTQ2208_RAMP_VALUE_MIN_uV);
	ramp_delay = min(ramp_delay, RTQ2208_RAMP_VALUE_MAX_uV);

	ramp_delay /= RTQ2208_RAMP_VALUE_MIN_uV;

	/*
	 * fls(ramp_delay) - 1: doing LSB shift, let it starts from 0
	 *
	 * RTQ2208_BUCK_RAMP_SEL_MASK - sel: doing descending order shifting.
	 * Because the relation of seleltion and value is like that
	 *
	 * seletion: value
	 * 010: 16mv
	 * ...
	 * 111: 0.5mv
	 *
	 * For example, if I would like to select 16mv, the fls(ramp_delay) - 1 will be 0b010,
	 * and I need to use 0b111 - sel to do the shifting
	 */

	sel = fls(ramp_delay) - 1;
	sel = RTQ2208_BUCK_RAMP_SEL_MASK - sel;

	val = FIELD_PREP(RTQ2208_BUCK_RSPUP_MASK, sel) | FIELD_PREP(RTQ2208_BUCK_RSPDN_MASK, sel);

	return regmap_update_bits(rdev->regmap, desc->ramp_reg,
				  RTQ2208_BUCK_RSPUP_MASK | RTQ2208_BUCK_RSPDN_MASK, val);
}

static int rtq2208_set_suspend_enable(struct regulator_dev *rdev)
{

Annotation

Implementation Notes