drivers/power/supply/ltc4162-l-charger.c

Source file repositories/reference/linux-study-clean/drivers/power/supply/ltc4162-l-charger.c

File Facts

System
Linux kernel
Corpus path
drivers/power/supply/ltc4162-l-charger.c
Extension
.c
Size
33024 bytes
Lines
1263
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 ltc4162l_chip_info {
	const char *name;
	int (*get_vbat)(struct ltc4162l_info *info, unsigned int reg,
			union power_supply_propval *val);
	int (*get_vcharge)(struct ltc4162l_info *info, unsigned int reg,
			   union power_supply_propval *val);
	int (*set_vcharge)(struct ltc4162l_info *info, unsigned int reg,
			   unsigned int value);
	int (*get_die_temp)(struct ltc4162l_info *info,
			    union power_supply_propval *val);
	unsigned int ibat_resolution_pv;
	unsigned int vin_resolution_uv;
	u8 telemetry_mask;
};

struct ltc4162l_info {
	struct i2c_client	*client;
	struct regmap		*regmap;
	struct power_supply	*charger;
	const struct ltc4162l_chip_info *chip_info;
	u32 rsnsb;	/* Series resistor that sets charge current, microOhm */
	u32 rsnsi;	/* Series resistor to measure input current, microOhm */
	u8 cell_count;	/* Number of connected cells, 0 while unknown */
};

static u8 ltc4162l_get_cell_count(struct ltc4162l_info *info)
{
	int ret;
	unsigned int val;

	/* Once read successfully */
	if (info->cell_count)
		return info->cell_count;

	ret = regmap_read(info->regmap, LTC4162L_CHEM_CELLS_REG, &val);
	if (ret)
		return 0;

	/* Lower 4 bits is the cell count, or 0 if the chip doesn't know yet */
	val &= 0x0f;
	if (!val)
		return 0;

	/* Once determined, keep the value */
	info->cell_count = val;

	return val;
};

static u8 ltc4162l_get_chem_type(struct ltc4162l_info *info)
{
	int ret;
	unsigned int val;

	ret = regmap_read(info->regmap, LTC4162L_CHEM_CELLS_REG, &val);
	if (ret)
		return ret;

	return FIELD_GET(LTC4162L_CHEM_MASK, val);
};

/* Convert enum value to POWER_SUPPLY_STATUS value */
static int ltc4162l_state_decode(enum ltc4162l_state value)
{
	switch (value) {
	case precharge:
	case cc_cv_charge:
		return POWER_SUPPLY_STATUS_CHARGING;
	case c_over_x_term:
		return POWER_SUPPLY_STATUS_FULL;
	case bat_missing_fault:
	case bat_short_fault:
		return POWER_SUPPLY_STATUS_UNKNOWN;
	default:
		return POWER_SUPPLY_STATUS_NOT_CHARGING;
	}
};

static int ltc4162l_get_status(struct ltc4162l_info *info,
			       union power_supply_propval *val)
{
	unsigned int regval;
	int ret;

	ret = regmap_read(info->regmap, LTC4162L_CHARGER_STATE, &regval);
	if (ret) {
		dev_err(&info->client->dev, "Failed to read CHARGER_STATE\n");
		return ret;
	}

Annotation

Implementation Notes