drivers/regulator/cros-ec-regulator.c

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

File Facts

System
Linux kernel
Corpus path
drivers/regulator/cros-ec-regulator.c
Extension
.c
Size
6044 bytes
Lines
229
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 cros_ec_regulator_data {
	struct regulator_desc desc;
	struct regulator_dev *dev;
	struct cros_ec_device *ec_dev;

	u32 index;

	u16 *voltages_mV;
	u16 num_voltages;
};

static int cros_ec_regulator_enable(struct regulator_dev *dev)
{
	struct cros_ec_regulator_data *data = rdev_get_drvdata(dev);
	struct ec_params_regulator_enable cmd = {
		.index = data->index,
		.enable = 1,
	};

	return cros_ec_cmd(data->ec_dev, 0, EC_CMD_REGULATOR_ENABLE, &cmd,
			   sizeof(cmd), NULL, 0);
}

static int cros_ec_regulator_disable(struct regulator_dev *dev)
{
	struct cros_ec_regulator_data *data = rdev_get_drvdata(dev);
	struct ec_params_regulator_enable cmd = {
		.index = data->index,
		.enable = 0,
	};

	return cros_ec_cmd(data->ec_dev, 0, EC_CMD_REGULATOR_ENABLE, &cmd,
			   sizeof(cmd), NULL, 0);
}

static int cros_ec_regulator_is_enabled(struct regulator_dev *dev)
{
	struct cros_ec_regulator_data *data = rdev_get_drvdata(dev);
	struct ec_params_regulator_is_enabled cmd = {
		.index = data->index,
	};
	struct ec_response_regulator_is_enabled resp;
	int ret;

	ret = cros_ec_cmd(data->ec_dev, 0, EC_CMD_REGULATOR_IS_ENABLED, &cmd,
			  sizeof(cmd), &resp, sizeof(resp));
	if (ret < 0)
		return ret;
	return resp.enabled;
}

static int cros_ec_regulator_list_voltage(struct regulator_dev *dev,
					  unsigned int selector)
{
	struct cros_ec_regulator_data *data = rdev_get_drvdata(dev);

	if (selector >= data->num_voltages)
		return -EINVAL;

	return data->voltages_mV[selector] * 1000;
}

static int cros_ec_regulator_get_voltage(struct regulator_dev *dev)
{
	struct cros_ec_regulator_data *data = rdev_get_drvdata(dev);
	struct ec_params_regulator_get_voltage cmd = {
		.index = data->index,
	};
	struct ec_response_regulator_get_voltage resp;
	int ret;

	ret = cros_ec_cmd(data->ec_dev, 0, EC_CMD_REGULATOR_GET_VOLTAGE, &cmd,
			  sizeof(cmd), &resp, sizeof(resp));
	if (ret < 0)
		return ret;
	return resp.voltage_mv * 1000;
}

static int cros_ec_regulator_set_voltage(struct regulator_dev *dev, int min_uV,
					 int max_uV, unsigned int *selector)
{
	struct cros_ec_regulator_data *data = rdev_get_drvdata(dev);
	int min_mV = DIV_ROUND_UP(min_uV, 1000);
	int max_mV = max_uV / 1000;
	struct ec_params_regulator_set_voltage cmd = {
		.index = data->index,
		.min_mv = min_mV,
		.max_mv = max_mV,
	};

Annotation

Implementation Notes