Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 02d0d275 authored by Daniel Mack's avatar Daniel Mack Committed by Anton Vorontsov
Browse files

ds2760_battery: add current_accum module parameter



When connecting a ds2760 to a partly loaded battery the first time,
there must be a way to bootstrap the current_accum value. Without that,
the current capactity value is bogus until the battery is fully charged
for the first time.

Signed-off-by: default avatarDaniel Mack <daniel@caiaq.de>
Cc: Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>
Cc: Matt Reimer <mreimer@vpop.net>
Signed-off-by: default avatarAnton Vorontsov <cbouatmailru@gmail.com>
parent 25f2bfa6
Loading
Loading
Loading
Loading
+27 −14
Original line number Diff line number Diff line
@@ -70,6 +70,10 @@ static unsigned int rated_capacity;
module_param(rated_capacity, uint, 0644);
MODULE_PARM_DESC(rated_capacity, "rated battery capacity, 10*mAh or index");

static unsigned int current_accum;
module_param(current_accum, uint, 0644);
MODULE_PARM_DESC(current_accum, "current accumulator value");

/* Some batteries have their rated capacity stored a N * 10 mAh, while
 * others use an index into this table. */
static int rated_capacities[] = {
@@ -215,6 +219,22 @@ static int ds2760_battery_read_status(struct ds2760_device_info *di)
	return 0;
}

static void ds2760_battery_set_current_accum(struct ds2760_device_info *di,
					     unsigned int acr_val)
{
	unsigned char acr[2];

	/* acr is in units of 0.25 mAh */
	acr_val *= 4L;
	acr_val /= 1000;

	acr[0] = acr_val >> 8;
	acr[1] = acr_val & 0xff;

	if (w1_ds2760_write(di->w1_dev, acr, DS2760_CURRENT_ACCUM_MSB, 2) < 2)
		dev_warn(di->dev, "ACR write failed\n");
}

static void ds2760_battery_update_status(struct ds2760_device_info *di)
{
	int old_charge_status = di->charge_status;
@@ -246,21 +266,9 @@ static void ds2760_battery_update_status(struct ds2760_device_info *di)
			if (di->full_counter < 2) {
				di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
			} else {
				unsigned char acr[2];
				int acr_val;

				/* acr is in units of 0.25 mAh */
				acr_val = di->full_active_uAh * 4L / 1000;

				acr[0] = acr_val >> 8;
				acr[1] = acr_val & 0xff;

				if (w1_ds2760_write(di->w1_dev, acr,
				    DS2760_CURRENT_ACCUM_MSB, 2) < 2)
					dev_warn(di->dev,
						 "ACR reset failed\n");

				di->charge_status = POWER_SUPPLY_STATUS_FULL;
				ds2760_battery_set_current_accum(di,
						di->full_active_uAh);
			}
		}
	} else {
@@ -423,6 +431,11 @@ static int ds2760_battery_probe(struct platform_device *pdev)
	if (rated_capacity)
		ds2760_battery_write_rated_capacity(di, rated_capacity);

	/* set current accumulator if given as parameter.
	 * this should only be done for bootstrapping the value */
	if (current_accum)
		ds2760_battery_set_current_accum(di, current_accum);

	retval = power_supply_register(&pdev->dev, &di->bat);
	if (retval) {
		dev_err(di->dev, "failed to register battery\n");