drivers/regulator/bd9576-regulator.c

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

File Facts

System
Linux kernel
Corpus path
drivers/regulator/bd9576-regulator.c
Extension
.c
Size
31715 bytes
Lines
1141
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 bd957x_regulator_data {
	struct regulator_desc desc;
	int base_voltage;
	struct regulator_dev *rdev;
	int ovd_notif;
	int uvd_notif;
	int temp_notif;
	int ovd_err;
	int uvd_err;
	int temp_err;
	const struct linear_range *xvd_ranges;
	int num_xvd_ranges;
	bool oc_supported;
	unsigned int ovd_reg;
	unsigned int uvd_reg;
	unsigned int xvd_mask;
	unsigned int ocp_reg;
	unsigned int ocp_mask;
	unsigned int ocw_reg;
	unsigned int ocw_mask;
	unsigned int ocw_rfet;
};

#define BD9576_NUM_REGULATORS 6
#define BD9576_NUM_OVD_REGULATORS 5

struct bd957x_data {
	struct bd957x_regulator_data regulator_data[BD9576_NUM_REGULATORS];
	struct regmap *regmap;
	struct delayed_work therm_irq_suppress;
	struct delayed_work ovd_irq_suppress;
	struct delayed_work uvd_irq_suppress;
	unsigned int therm_irq;
	unsigned int ovd_irq;
	unsigned int uvd_irq;
	spinlock_t err_lock;
	int regulator_global_err;
};

static int bd957x_vout34_list_voltage(struct regulator_dev *rdev,
				      unsigned int selector)
{
	const struct regulator_desc *desc = rdev->desc;
	int multiplier = selector & desc->vsel_mask & 0x7f;
	int tune;

	/* VOUT3 and 4 has 10mV step */
	tune = multiplier * 10000;

	if (!(selector & 0x80))
		return desc->fixed_uV - tune;

	return desc->fixed_uV + tune;
}

static int bd957x_list_voltage(struct regulator_dev *rdev,
			       unsigned int selector)
{
	const struct regulator_desc *desc = rdev->desc;
	int index = selector & desc->vsel_mask & 0x7f;

	if (!(selector & 0x80))
		index += desc->n_voltages/2;

	if (index >= desc->n_voltages)
		return -EINVAL;

	return desc->volt_table[index];
}

static void bd9576_fill_ovd_flags(struct bd957x_regulator_data *data,
				  bool warn)
{
	if (warn) {
		data->ovd_notif = REGULATOR_EVENT_OVER_VOLTAGE_WARN;
		data->ovd_err = REGULATOR_ERROR_OVER_VOLTAGE_WARN;
	} else {
		data->ovd_notif = REGULATOR_EVENT_REGULATION_OUT;
		data->ovd_err = REGULATOR_ERROR_REGULATION_OUT;
	}
}

static void bd9576_fill_ocp_flags(struct bd957x_regulator_data *data,
				  bool warn)
{
	if (warn) {
		data->uvd_notif = REGULATOR_EVENT_OVER_CURRENT_WARN;
		data->uvd_err = REGULATOR_ERROR_OVER_CURRENT_WARN;
	} else {
		data->uvd_notif = REGULATOR_EVENT_OVER_CURRENT;

Annotation

Implementation Notes