drivers/power/supply/stc3117_fuel_gauge.c

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

File Facts

System
Linux kernel
Corpus path
drivers/power/supply/stc3117_fuel_gauge.c
Extension
.c
Size
16805 bytes
Lines
613
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 stc3117_battery_info {
	int voltage_min_mv;
	int voltage_max_mv;
	int battery_capacity_mah;
	int sense_resistor;
};

struct stc3117_data {
	struct i2c_client *client;
	struct regmap *regmap;
	struct delayed_work update_work;
	struct power_supply *battery;
	union stc3117_internal_ram ram_data;
	struct stc3117_battery_info battery_info;

	u8 soc_tab[16];
	int cc_cnf;
	int vm_cnf;
	int cc_adj;
	int vm_adj;
	int avg_current;
	int avg_voltage;
	int batt_current;
	int voltage;
	int temp;
	int soc;
	int ocv;
	int hrsoc;
	int presence;
};

static int stc3117_convert(int value, int factor)
{
	value = (value * factor) / 4096;
	return value * 1000;
}

static int stc3117_get_battery_data(struct stc3117_data *data)
{
	u8 reg_list[16];
	u8 data_adjust[4];
	int value, mode;

	regmap_bulk_read(data->regmap, STC3117_ADDR_MODE,
			 reg_list, sizeof(reg_list));

	/* soc */
	value = (reg_list[3] << 8) + reg_list[2];
	data->hrsoc = value;
	data->soc = (value * 10 + 256) / 512;

	/* current in uA*/
	value = (reg_list[7] << 8) + reg_list[6];
	data->batt_current = stc3117_convert(value,
			CURRENT_LSB_VALUE / data->battery_info.sense_resistor);

	/* voltage in uV */
	value = (reg_list[9] << 8) + reg_list[8];
	data->voltage = stc3117_convert(value, VOLTAGE_LSB_VALUE);

	/* temp in 1/10 °C */
	data->temp = reg_list[10] * 10;

	/* Avg current in uA */
	value = (reg_list[12] << 8) + reg_list[11];
	regmap_read(data->regmap, STC3117_ADDR_MODE, &mode);
	if (!(mode & STC3117_VMODE)) {
		value = stc3117_convert(value,
			CURRENT_LSB_VALUE / data->battery_info.sense_resistor);
		value = value / 4;
	} else {
		value = stc3117_convert(value, 36 * STC3117_NOMINAL_CAPACITY);
	}
	data->avg_current = value;

	/* ocv in uV */
	value = (reg_list[14] << 8) + reg_list[13];
	value = stc3117_convert(value, VOLTAGE_LSB_VALUE);
	value = (value + 2) / 4;
	data->ocv = value;

	/* CC & VM adjustment counters */
	regmap_bulk_read(data->regmap, STC3117_ADDR_CC_ADJ_L,
			 data_adjust, sizeof(data_adjust));
	value = (data_adjust[1] << 8) + data_adjust[0];
	data->cc_adj = value;

	value = (data_adjust[3] << 8) + data_adjust[2];
	data->vm_adj = value;

Annotation

Implementation Notes