drivers/power/supply/max8998_charger.c

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

File Facts

System
Linux kernel
Corpus path
drivers/power/supply/max8998_charger.c
Extension
.c
Size
5438 bytes
Lines
210
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 max8998_battery_data {
	struct device *dev;
	struct max8998_dev *iodev;
	struct power_supply *battery;
};

static enum power_supply_property max8998_battery_props[] = {
	POWER_SUPPLY_PROP_PRESENT, /* the presence of battery */
	POWER_SUPPLY_PROP_ONLINE, /* charger is active or not */
	POWER_SUPPLY_PROP_STATUS, /* charger is charging/discharging/full */
};

/* Note that the charger control is done by a current regulator "CHARGER" */
static int max8998_battery_get_property(struct power_supply *psy,
		enum power_supply_property psp,
		union power_supply_propval *val)
{
	struct max8998_battery_data *max8998 = power_supply_get_drvdata(psy);
	struct i2c_client *i2c = max8998->iodev->i2c;
	int ret;
	u8 reg;

	switch (psp) {
	case POWER_SUPPLY_PROP_PRESENT:
		ret = max8998_read_reg(i2c, MAX8998_REG_STATUS2, &reg);
		if (ret)
			return ret;
		if (reg & (1 << 4))
			val->intval = 0;
		else
			val->intval = 1;
		break;
	case POWER_SUPPLY_PROP_ONLINE:
		ret = max8998_read_reg(i2c, MAX8998_REG_STATUS2, &reg);
		if (ret)
			return ret;

		if (reg & (1 << 5))
			val->intval = 1;
		else
			val->intval = 0;

		break;
	case POWER_SUPPLY_PROP_STATUS:
		ret = max8998_read_reg(i2c, MAX8998_REG_STATUS2, &reg);
		if (ret)
			return ret;

		if (!(reg & (1 << 5))) {
			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
		} else {
			if (reg & (1 << 6))
				val->intval = POWER_SUPPLY_STATUS_FULL;
			else if (reg & (1 << 3))
				val->intval = POWER_SUPPLY_STATUS_CHARGING;
			else
				val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
		}
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static const struct power_supply_desc max8998_battery_desc = {
	.name		= "max8998_pmic",
	.type		= POWER_SUPPLY_TYPE_BATTERY,
	.get_property	= max8998_battery_get_property,
	.properties	= max8998_battery_props,
	.num_properties	= ARRAY_SIZE(max8998_battery_props),
};

static int max8998_battery_probe(struct platform_device *pdev)
{
	struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent);
	struct max8998_platform_data *pdata = iodev->pdata;
	struct power_supply_config psy_cfg = {};
	struct max8998_battery_data *max8998;
	struct i2c_client *i2c;
	int ret = 0;

	if (!pdata) {
		dev_err(pdev->dev.parent, "No platform init data supplied\n");
		return -ENODEV;
	}

	max8998 = devm_kzalloc(&pdev->dev, sizeof(struct max8998_battery_data),
				GFP_KERNEL);

Annotation

Implementation Notes