drivers/regulator/max77802-regulator.c

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

File Facts

System
Linux kernel
Corpus path
drivers/regulator/max77802-regulator.c
Extension
.c
Size
18172 bytes
Lines
568
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 max77802_regulator_prv {
	/* Array indexed by regulator id */
	unsigned int opmode[MAX77802_REG_MAX];
};

static inline unsigned int max77802_map_mode(unsigned int mode)
{
	return mode == MAX77802_OPMODE_NORMAL ?
		REGULATOR_MODE_NORMAL : REGULATOR_MODE_STANDBY;
}

static int max77802_get_opmode_shift(int id)
{
	if (id == MAX77802_BUCK1 || (id >= MAX77802_BUCK5 &&
				     id <= MAX77802_BUCK10))
		return 0;

	if (id >= MAX77802_BUCK2 && id <= MAX77802_BUCK4)
		return MAX77802_OPMODE_BUCK234_SHIFT;

	if (id >= MAX77802_LDO1 && id <= MAX77802_LDO35)
		return MAX77802_OPMODE_SHIFT_LDO;

	return -EINVAL;
}

/**
 * max77802_set_suspend_disable - Disable the regulator during system suspend
 * @rdev: regulator to mark as disabled
 *
 * All regulators expect LDO 1, 3, 20 and 21 support OFF by PWRREQ.
 * Configure the regulator so the PMIC will turn it OFF during system suspend.
 */
static int max77802_set_suspend_disable(struct regulator_dev *rdev)
{
	unsigned int val = MAX77802_OFF_PWRREQ;
	struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
	unsigned int id = rdev_get_id(rdev);
	int shift = max77802_get_opmode_shift(id);

	if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode)))
		return -EINVAL;
	max77802->opmode[id] = val;
	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
				  rdev->desc->enable_mask, val << shift);
}

/*
 * Some LDOs support Low Power Mode while the system is running.
 *
 * LDOs 1, 3, 20, 21.
 */
static int max77802_set_mode(struct regulator_dev *rdev, unsigned int mode)
{
	struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
	unsigned int id = rdev_get_id(rdev);
	unsigned int val;
	int shift = max77802_get_opmode_shift(id);

	switch (mode) {
	case REGULATOR_MODE_STANDBY:
		val = MAX77802_OPMODE_LP;	/* ON in Low Power Mode */
		break;
	case REGULATOR_MODE_NORMAL:
		val = MAX77802_OPMODE_NORMAL;	/* ON in Normal Mode */
		break;
	default:
		dev_warn(&rdev->dev, "%s: regulator mode: 0x%x not supported\n",
			 rdev->desc->name, mode);
		return -EINVAL;
	}

	if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode)))
		return -EINVAL;

	max77802->opmode[id] = val;
	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
				  rdev->desc->enable_mask, val << shift);
}

static unsigned max77802_get_mode(struct regulator_dev *rdev)
{
	struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
	unsigned int id = rdev_get_id(rdev);

	if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode)))
		return -EINVAL;
	return max77802_map_mode(max77802->opmode[id]);
}

Annotation

Implementation Notes