drivers/power/supply/rt9756.c

Source file repositories/reference/linux-study-clean/drivers/power/supply/rt9756.c

File Facts

System
Linux kernel
Corpus path
drivers/power/supply/rt9756.c
Extension
.c
Size
25852 bytes
Lines
956
Domain
Driver Families
Bucket
drivers/power
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 charger_event {
	unsigned int flag1;
	unsigned int flag2;
	unsigned int flag3;
	unsigned int flag4;
};

struct rt9756_data {
	struct device *dev;
	struct regmap *regmap;
	struct regmap_field *rm_fields[F_MAX_FIELD];
	struct power_supply *psy;
	struct power_supply *bat_psy;
	struct mutex adc_lock;
	struct power_supply_desc psy_desc;
	struct power_supply_desc bat_psy_desc;
	struct charger_event chg_evt;
	unsigned int rg_resistor;
	unsigned int real_resistor;
	enum rt9756_model model;
	atomic_t usb_type;
};

struct rt975x_dev_data {
	const struct regmap_config *regmap_config;
	const struct reg_field *reg_fields;
	const struct reg_sequence *init_regs;
	size_t num_init_regs;
	int (*check_device_model)(struct rt9756_data *data);
};

static int rt9756_get_value_field_range(struct rt9756_data *data, enum rt9756_fields en_field,
					enum rt9756_fields field, enum rt9756_ranges rsel, int *val)
{
	const struct linear_range *range = rt9756_chg_ranges + rsel;
	unsigned int enable, selector, value;
	int ret;

	ret = regmap_field_read(data->rm_fields[en_field], &enable);
	if (ret)
		return ret;

	if (!enable) {
		*val = 0;
		return 0;
	}

	ret = regmap_field_read(data->rm_fields[field], &selector);
	if (ret)
		return ret;

	ret = linear_range_get_value(range, selector, &value);
	if (ret)
		return ret;

	*val = (int)value;

	return 0;
}

static int rt9756_set_value_field_range(struct rt9756_data *data, enum rt9756_fields en_field,
					enum rt9756_fields field, enum rt9756_ranges rsel, int val)
{
	const struct linear_range *range = rt9756_chg_ranges + rsel;
	unsigned int selector, value;
	int ret;

	if (!val)
		return regmap_field_write(data->rm_fields[en_field], 0);

	value = (unsigned int)val;
	linear_range_get_selector_within(range, value, &selector);
	ret = regmap_field_write(data->rm_fields[field], selector);
	if (ret)
		return ret;

	return regmap_field_write(data->rm_fields[en_field], 1);
}

static int rt9756_get_adc(struct rt9756_data *data, enum rt9756_adc_chan chan,
			  int *val)
{
	struct regmap *regmap = data->regmap;
	unsigned int reg_addr = RT9756_REG_VBUSADC + chan * 2;
	unsigned int mask = RT9756_ADCEN_MASK | RT9756_ADCONCE_MASK;
	unsigned int shift = 0, adc_cntl;
	__be16 raws;
	int scale, offset = 0, ret;

	guard(mutex)(&data->adc_lock);

Annotation

Implementation Notes