drivers/power/supply/da9052-battery.c

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

File Facts

System
Linux kernel
Corpus path
drivers/power/supply/da9052-battery.c
Extension
.c
Size
15419 bytes
Lines
662
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 da9052_battery {
	struct da9052 *da9052;
	struct power_supply *psy;
	struct notifier_block nb;
	int charger_type;
	int status;
	int health;
};

static inline int volt_reg_to_mV(int value)
{
	return ((value * 1000) / 512) + 2500;
}

static inline int ichg_reg_to_mA(int value)
{
	return (value * 3900) / 1000;
}

static int da9052_read_chgend_current(struct da9052_battery *bat,
				       int *current_mA)
{
	int ret;

	if (bat->status == POWER_SUPPLY_STATUS_DISCHARGING)
		return -EINVAL;

	ret = da9052_reg_read(bat->da9052, DA9052_ICHG_END_REG);
	if (ret < 0)
		return ret;

	*current_mA = ichg_reg_to_mA(ret & DA9052_ICHGEND_ICHGEND);

	return 0;
}

static int da9052_read_chg_current(struct da9052_battery *bat, int *current_mA)
{
	int ret;

	if (bat->status == POWER_SUPPLY_STATUS_DISCHARGING)
		return -EINVAL;

	ret = da9052_reg_read(bat->da9052, DA9052_ICHG_AV_REG);
	if (ret < 0)
		return ret;

	*current_mA = ichg_reg_to_mA(ret & DA9052_ICHGAV_ICHGAV);

	return 0;
}

static int da9052_bat_check_status(struct da9052_battery *bat, int *status)
{
	u8 v[2] = {0, 0};
	u8 bat_status;
	u8 chg_end;
	int ret;
	int chg_current;
	int chg_end_current;
	bool dcinsel;
	bool dcindet;
	bool vbussel;
	bool vbusdet;
	bool dc;
	bool vbus;

	ret = da9052_group_read(bat->da9052, DA9052_STATUS_A_REG, 2, v);
	if (ret < 0)
		return ret;

	bat_status = v[0];
	chg_end = v[1];

	dcinsel = bat_status & DA9052_STATUSA_DCINSEL;
	dcindet = bat_status & DA9052_STATUSA_DCINDET;
	vbussel = bat_status & DA9052_STATUSA_VBUSSEL;
	vbusdet = bat_status & DA9052_STATUSA_VBUSDET;
	dc = dcinsel && dcindet;
	vbus = vbussel && vbusdet;

	/* Preference to WALL(DCIN) charger unit */
	if (dc || vbus) {
		bat->charger_type = DA9052_CHARGER;

		/* If charging end flag is set and Charging current is greater
		 * than charging end limit then battery is charging
		*/
		if ((chg_end & DA9052_STATUSB_CHGEND) != 0) {
			ret = da9052_read_chg_current(bat, &chg_current);

Annotation

Implementation Notes