drivers/regulator/rt5120-regulator.c

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

File Facts

System
Linux kernel
Corpus path
drivers/regulator/rt5120-regulator.c
Extension
.c
Size
11837 bytes
Lines
422
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 rt5120_priv {
	struct device *dev;
	struct regmap *regmap;
	struct regulator_desc rdesc[RT5120_MAX_REGULATOR];
};

static int rt5120_buck_set_mode(struct regulator_dev *rdev, unsigned int mode)
{
	struct regmap *regmap = rdev_get_regmap(rdev);
	int rid = rdev_get_id(rdev);
	unsigned int mask = RT5120_FPWM_MASK(rid), val;

	switch (mode) {
	case REGULATOR_MODE_NORMAL:
		val = 0;
		break;
	case REGULATOR_MODE_FAST:
		val = RT5120_FPWM_MASK(rid);
		break;
	default:
		return -EINVAL;
	}

	return regmap_update_bits(regmap, RT5120_REG_MODECTL, mask, val);
}

static unsigned int rt5120_buck_get_mode(struct regulator_dev *rdev)
{
	struct regmap *regmap = rdev_get_regmap(rdev);
	int ret, rid = rdev_get_id(rdev);
	unsigned int val;

	ret = regmap_read(regmap, RT5120_REG_MODECTL, &val);
	if (ret)
		return REGULATOR_MODE_INVALID;

	if (val & RT5120_FPWM_MASK(rid))
		return REGULATOR_MODE_FAST;

	return REGULATOR_MODE_NORMAL;
}

static int rt5120_regulator_get_error_flags(struct regulator_dev *rdev,
					    unsigned int *flags)
{
	struct regmap *regmap = rdev_get_regmap(rdev);
	unsigned int stat, hd_stat, cur_flags = 0;
	int rid = rdev_get_id(rdev), ret;

	/*
	 * reg 0x03/0x04/0x05 to indicate PG/UV/OV
	 * use block read to descrease I/O xfer time
	 */
	ret = regmap_raw_read(regmap, RT5120_REG_PGSTAT, &stat, 3);
	if (ret)
		return ret;

	ret = regmap_read(regmap, RT5120_REG_INTSTAT, &hd_stat);
	if (ret)
		return ret;

	if (!(stat & RT5120_OUTPG_MASK(rid))) {
		if (stat & RT5120_OUTUV_MASK(rid))
			cur_flags |= REGULATOR_ERROR_UNDER_VOLTAGE;

		if (stat & RT5120_OUTOV_MASK(rid))
			cur_flags |= REGULATOR_ERROR_REGULATION_OUT;
	}

	if (hd_stat & RT5120_HOTDIE_MASK)
		cur_flags |= REGULATOR_ERROR_OVER_TEMP;

	*flags = cur_flags;
	return 0;
}

static int rt5120_buck1_set_suspend_voltage(struct regulator_dev *rdev, int uV)
{
	struct regmap *regmap = rdev_get_regmap(rdev);
	int sel;

	if (uV < RT5120_BUCK1_MINUV || uV > RT5120_BUCK1_MAXUV)
		return -EINVAL;

	sel = (uV - RT5120_BUCK1_MINUV) / RT5120_BUCK1_STEPUV;
	return regmap_write(regmap, RT5120_REG_CH1SLPVID, sel);
}

static int rt5120_regulator_set_suspend_enable(struct regulator_dev *rdev)
{

Annotation

Implementation Notes