drivers/power/supply/pm8916_lbc.c

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

File Facts

System
Linux kernel
Corpus path
drivers/power/supply/pm8916_lbc.c
Extension
.c
Size
10612 bytes
Lines
382
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 pm8916_lbc_charger {
	struct device *dev;
	struct extcon_dev *edev;
	struct power_supply *charger;
	struct power_supply_battery_info *info;
	struct regmap *regmap;
	unsigned int reg[4];
	bool online;
	unsigned int charge_voltage_max;
	unsigned int charge_voltage_safe;
	unsigned int charge_current_max;
	unsigned int charge_current_safe;
};

static const unsigned int pm8916_lbc_charger_cable[] = {
	EXTCON_USB,
	EXTCON_NONE,
};

enum {
	LBC_CHGR = 0,
	LBC_BAT_IF,
	LBC_USB,
	LBC_MISC,
};

static int pm8916_lbc_charger_configure(struct pm8916_lbc_charger *chg)
{
	int ret = 0;
	unsigned int tmp;

	chg->charge_voltage_max = clamp_t(u32, chg->charge_voltage_max,
					  PM8916_LBC_CHGR_MIN_VOLTAGE, chg->charge_voltage_safe);

	tmp = chg->charge_voltage_max - PM8916_LBC_CHGR_MIN_VOLTAGE;
	tmp /= PM8916_LBC_CHGR_VOLTAGE_STEP;
	chg->charge_voltage_max = PM8916_LBC_CHGR_MIN_VOLTAGE + tmp * PM8916_LBC_CHGR_VOLTAGE_STEP;

	ret = regmap_write(chg->regmap, chg->reg[LBC_CHGR] + PM8916_LBC_CHGR_VDD_MAX, tmp);
	if (ret)
		goto error;

	chg->charge_current_max = min(chg->charge_current_max, chg->charge_current_safe);

	tmp = clamp_t(u32, chg->charge_current_max,
		      PM8916_LBC_CHGR_MIN_CURRENT, PM8916_LBC_CHGR_MAX_CURRENT);

	tmp = chg->charge_current_max / PM8916_LBC_CHGR_MIN_CURRENT - 1;
	chg->charge_current_max = (tmp + 1) * PM8916_LBC_CHGR_MIN_CURRENT;

	ret = regmap_write(chg->regmap, chg->reg[LBC_CHGR] + PM8916_LBC_CHGR_IBAT_MAX, tmp);
	if (ret)
		goto error;

	ret = regmap_write(chg->regmap, chg->reg[LBC_CHGR] + PM8916_LBC_CHGR_CHG_CTRL,
			   PM8916_LBC_CHGR_CHG_EN | PM8916_LBC_CHGR_PSTG_EN);
	if (ret)
		goto error;

	return ret;

error:
	dev_err(chg->dev, "Failed to configure charging: %pe\n", ERR_PTR(ret));
	return ret;
}

static int pm8916_lbc_charger_get_property(struct power_supply *psy,
					   enum power_supply_property psp,
					   union power_supply_propval *val)
{
	struct pm8916_lbc_charger *chg = power_supply_get_drvdata(psy);

	switch (psp) {
	case POWER_SUPPLY_PROP_ONLINE:
		val->intval = chg->online;
		return 0;

	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
		val->intval = chg->charge_voltage_max;
		return 0;

	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
		val->intval = chg->charge_current_max;
		return 0;

	default:
		return -EINVAL;
	};
}

Annotation

Implementation Notes