drivers/power/supply/sbs-manager.c

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

File Facts

System
Linux kernel
Corpus path
drivers/power/supply/sbs-manager.c
Extension
.c
Size
10352 bytes
Lines
421
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 sbsm_data {
	struct i2c_client *client;
	struct i2c_mux_core *muxc;

	struct power_supply *psy;

	u8 cur_chan;          /* currently selected channel */
	struct gpio_chip chip;
	bool is_ltc1760;      /* special capabilities */

	unsigned int supported_bats;
	unsigned int last_state;
	unsigned int last_state_cont;
};

static enum power_supply_property sbsm_props[] = {
	POWER_SUPPLY_PROP_ONLINE,
	POWER_SUPPLY_PROP_CHARGE_TYPE,
};

static int sbsm_read_word(struct i2c_client *client, u8 address)
{
	int reg, retries;

	for (retries = SBSM_RETRY_CNT; retries > 0; retries--) {
		reg = i2c_smbus_read_word_data(client, address);
		if (reg >= 0)
			break;
	}

	if (reg < 0) {
		dev_err(&client->dev, "failed to read register 0x%02x\n",
			address);
	}

	return reg;
}

static int sbsm_write_word(struct i2c_client *client, u8 address, u16 word)
{
	int ret, retries;

	for (retries = SBSM_RETRY_CNT; retries > 0; retries--) {
		ret = i2c_smbus_write_word_data(client, address, word);
		if (ret >= 0)
			break;
	}
	if (ret < 0)
		dev_err(&client->dev, "failed to write to register 0x%02x\n",
			address);

	return ret;
}

static int sbsm_get_property(struct power_supply *psy,
			     enum power_supply_property psp,
			     union power_supply_propval *val)
{
	struct sbsm_data *data = power_supply_get_drvdata(psy);
	int regval = 0;

	switch (psp) {
	case POWER_SUPPLY_PROP_ONLINE:
		regval = sbsm_read_word(data->client, SBSM_CMD_BATSYSSTATECONT);
		if (regval < 0)
			return regval;
		val->intval = !!(regval & SBSM_BIT_AC_PRESENT);
		break;

	case POWER_SUPPLY_PROP_CHARGE_TYPE:
		regval = sbsm_read_word(data->client, SBSM_CMD_BATSYSSTATE);
		if (regval < 0)
			return regval;

		if ((regval & SBSM_MASK_CHARGE_BAT) == 0) {
			val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
			return 0;
		}
		val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;

		if (data->is_ltc1760) {
			/* charge mode fast if turbo is active */
			regval = sbsm_read_word(data->client, SBSM_CMD_LTC);
			if (regval < 0)
				return regval;
			else if (regval & SBSM_BIT_TURBO)
				val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST;
		}
		break;

Annotation

Implementation Notes