drivers/regulator/qcom-pm8008-regulator.c

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

File Facts

System
Linux kernel
Corpus path
drivers/regulator/qcom-pm8008-regulator.c
Extension
.c
Size
5193 bytes
Lines
199
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 pm8008_regulator {
	struct regmap		*regmap;
	struct regulator_desc	desc;
	unsigned int		base;
};

struct pm8008_regulator_data {
	const char			*name;
	const char			*supply_name;
	unsigned int			base;
	int				min_dropout_uV;
	const struct linear_range	*voltage_range;
};

static const struct linear_range nldo_ranges[] = {
	REGULATOR_LINEAR_RANGE(528000, 0, 122, 8000),
};

static const struct linear_range pldo_ranges[] = {
	REGULATOR_LINEAR_RANGE(1504000, 0, 237, 8000),
};

static const struct pm8008_regulator_data pm8008_reg_data[] = {
	{ "ldo1", "vdd-l1-l2", 0x4000, 225000, nldo_ranges, },
	{ "ldo2", "vdd-l1-l2", 0x4100, 225000, nldo_ranges, },
	{ "ldo3", "vdd-l3-l4", 0x4200, 300000, pldo_ranges, },
	{ "ldo4", "vdd-l3-l4", 0x4300, 300000, pldo_ranges, },
	{ "ldo5", "vdd-l5",    0x4400, 200000, pldo_ranges, },
	{ "ldo6", "vdd-l6",    0x4500, 200000, pldo_ranges, },
	{ "ldo7", "vdd-l7",    0x4600, 200000, pldo_ranges, },
};

static int pm8008_regulator_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel)
{
	struct pm8008_regulator *preg = rdev_get_drvdata(rdev);
	unsigned int mV;
	__le16 val;
	int ret;

	ret = regulator_list_voltage_linear_range(rdev, sel);
	if (ret < 0)
		return ret;

	mV = DIV_ROUND_UP(ret, 1000);

	val = cpu_to_le16(mV);

	ret = regmap_bulk_write(preg->regmap, preg->base + LDO_VSET_LB_REG,
			&val, sizeof(val));
	if (ret < 0)
		return ret;

	return 0;
}

static int pm8008_regulator_get_voltage_sel(struct regulator_dev *rdev)
{
	struct pm8008_regulator *preg = rdev_get_drvdata(rdev);
	unsigned int uV;
	__le16 val;
	int ret;

	ret = regmap_bulk_read(preg->regmap, preg->base + LDO_VSET_LB_REG,
			&val, sizeof(val));
	if (ret < 0)
		return ret;

	uV = le16_to_cpu(val) * 1000;

	return regulator_map_voltage_linear_range(rdev, uV, INT_MAX);
}

static const struct regulator_ops pm8008_regulator_ops = {
	.list_voltage		= regulator_list_voltage_linear,
	.set_voltage_sel	= pm8008_regulator_set_voltage_sel,
	.get_voltage_sel	= pm8008_regulator_get_voltage_sel,
	.enable			= regulator_enable_regmap,
	.disable		= regulator_disable_regmap,
	.is_enabled		= regulator_is_enabled_regmap,
};

static int pm8008_regulator_probe(struct platform_device *pdev)
{
	const struct pm8008_regulator_data *data;
	struct regulator_config config = {};
	struct device *dev = &pdev->dev;
	struct pm8008_regulator *preg;
	struct regulator_desc *desc;
	struct regulator_dev *rdev;
	struct regmap *regmap;

Annotation

Implementation Notes