drivers/regulator/max77686-regulator.c

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

File Facts

System
Linux kernel
Corpus path
drivers/regulator/max77686-regulator.c
Extension
.c
Size
16374 bytes
Lines
539
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 max77686_data {
	struct device *dev;
	DECLARE_BITMAP(gpio_enabled, MAX77686_REGULATORS);

	/* Array indexed by regulator id */
	unsigned int opmode[MAX77686_REGULATORS];
};

static unsigned int max77686_get_opmode_shift(int id)
{
	switch (id) {
	case MAX77686_BUCK1:
	case MAX77686_BUCK5 ... MAX77686_BUCK9:
		return 0;
	case MAX77686_BUCK2 ... MAX77686_BUCK4:
		return MAX77686_OPMODE_BUCK234_SHIFT;
	default:
		/* all LDOs */
		return MAX77686_OPMODE_SHIFT;
	}
}

/*
 * When regulator is configured for GPIO control then it
 * replaces "normal" mode. Any change from low power mode to normal
 * should actually change to GPIO control.
 * Map normal mode to proper value for such regulators.
 */
static unsigned int max77686_map_normal_mode(struct max77686_data *max77686,
					     int id)
{
	switch (id) {
	case MAX77686_BUCK8:
	case MAX77686_BUCK9:
	case MAX77686_LDO20 ... MAX77686_LDO22:
		if (test_bit(id, max77686->gpio_enabled))
			return MAX77686_GPIO_CONTROL;
	}

	return MAX77686_NORMAL;
}

/* Some BUCKs and LDOs supports Normal[ON/OFF] mode during suspend */
static int max77686_set_suspend_disable(struct regulator_dev *rdev)
{
	unsigned int val, shift;
	struct max77686_data *max77686 = rdev_get_drvdata(rdev);
	int ret, id = rdev_get_id(rdev);

	shift = max77686_get_opmode_shift(id);
	val = MAX77686_OFF_PWRREQ;

	ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
				 rdev->desc->enable_mask, val << shift);
	if (ret)
		return ret;

	max77686->opmode[id] = val;
	return 0;
}

/* Some LDOs supports [LPM/Normal]ON mode during suspend state */
static int max77686_set_suspend_mode(struct regulator_dev *rdev,
				     unsigned int mode)
{
	struct max77686_data *max77686 = rdev_get_drvdata(rdev);
	unsigned int val;
	int ret, id = rdev_get_id(rdev);

	/* BUCK[5-9] doesn't support this feature */
	if (id >= MAX77686_BUCK5)
		return 0;

	switch (mode) {
	case REGULATOR_MODE_IDLE:			/* ON in LP Mode */
		val = MAX77686_LDO_LOWPOWER_PWRREQ;
		break;
	case REGULATOR_MODE_NORMAL:			/* ON in Normal Mode */
		val = max77686_map_normal_mode(max77686, id);
		break;
	default:
		pr_warn("%s: regulator_suspend_mode : 0x%x not supported\n",
			rdev->desc->name, mode);
		return -EINVAL;
	}

	ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
				  rdev->desc->enable_mask,
				  val << MAX77686_OPMODE_SHIFT);
	if (ret)

Annotation

Implementation Notes