drivers/power/supply/88pm860x_charger.c

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

File Facts

System
Linux kernel
Corpus path
drivers/power/supply/88pm860x_charger.c
Extension
.c
Size
18764 bytes
Lines
738
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 pm860x_charger_info {
	struct pm860x_chip *chip;
	struct i2c_client *i2c;
	struct i2c_client *i2c_8606;
	struct device *dev;

	struct power_supply *usb;
	struct mutex lock;
	int irq_nums;
	int irq[7];
	unsigned state:3;	/* fsm state */
	unsigned online:1;	/* usb charger */
	unsigned present:1;	/* battery present */
	unsigned allowed:1;
};

static char *pm860x_supplied_to[] = {
	"battery-monitor",
};

static int measure_vchg(struct pm860x_charger_info *info, int *data)
{
	unsigned char buf[2];
	int ret = 0;

	ret = pm860x_bulk_read(info->i2c, PM8607_VCHG_MEAS1, 2, buf);
	if (ret < 0)
		return ret;

	*data = ((buf[0] & 0xff) << 4) | (buf[1] & 0x0f);
	/* V_BATT_MEAS(mV) = value * 5 * 1.8 * 1000 / (2^12) */
	*data = ((*data & 0xfff) * 9 * 125) >> 9;

	dev_dbg(info->dev, "%s, vchg: %d mv\n", __func__, *data);

	return ret;
}

static void set_vchg_threshold(struct pm860x_charger_info *info,
			       int min, int max)
{
	int data;

	/* (tmp << 8) * / 5 / 1800 */
	if (min <= 0)
		data = 0;
	else
		data = (min << 5) / 1125;
	pm860x_reg_write(info->i2c, PM8607_VCHG_LOWTH, data);
	dev_dbg(info->dev, "VCHG_LOWTH:%dmv, 0x%x\n", min, data);

	if (max <= 0)
		data = 0xff;
	else
		data = (max << 5) / 1125;
	pm860x_reg_write(info->i2c, PM8607_VCHG_HIGHTH, data);
	dev_dbg(info->dev, "VCHG_HIGHTH:%dmv, 0x%x\n", max, data);

}

static void set_vbatt_threshold(struct pm860x_charger_info *info,
				int min, int max)
{
	int data;

	/* (tmp << 8) * 3 / 1800 */
	if (min <= 0)
		data = 0;
	else
		data = (min << 5) / 675;
	pm860x_reg_write(info->i2c, PM8607_VBAT_LOWTH, data);
	dev_dbg(info->dev, "VBAT Min:%dmv, LOWTH:0x%x\n", min, data);

	if (max <= 0)
		data = 0xff;
	else
		data = (max << 5) / 675;
	pm860x_reg_write(info->i2c, PM8607_VBAT_HIGHTH, data);
	dev_dbg(info->dev, "VBAT Max:%dmv, HIGHTH:0x%x\n", max, data);

	return;
}

static int start_precharge(struct pm860x_charger_info *info)
{
	int ret;

	dev_dbg(info->dev, "Start Pre-charging!\n");
	set_vbatt_threshold(info, 0, 0);

Annotation

Implementation Notes