Received: by 2002:ac0:aa62:0:0:0:0:0 with SMTP id w31-v6csp1469079ima; Sun, 21 Oct 2018 12:28:08 -0700 (PDT) X-Google-Smtp-Source: ACcGV6089CM4t80xA3pcTySHZX5jheCVhzDCjyevjwOHQ++UG5eDMSt6xjeo8uYSSZQXqIDL0dsb X-Received: by 2002:a17:902:1c3:: with SMTP id b61-v6mr29148353plb.65.1540150088202; Sun, 21 Oct 2018 12:28:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1540150088; cv=none; d=google.com; s=arc-20160816; b=uBzFBSXSyGlHg6NzYEal+u2AT9hq0Rb8myVtkgz0a7DJiStkHKA8Fada2LKnHJ3Xqg lO5gjFZi826uPq8328VzmCG7CcYhJFkfr1lcMfD8OJ92McavALH9LqTamnDiFTyMfZUI mVXiwjXsr5X7ESjg1pLQHyFeA5B6exF7aw14itIu/QYLq1cdMB1Dikvy3l1fO+6do+5v 6BrAcc8i+KlJGSeWG/6fZL6Sor29Ugx7gp5t+23Ds6IShYYyECBxvHSNcg/0Woeel5Fx TR1FTKDou1EwE5lec1mEStLPz5Z4xn0Y6tcxG+6i9Gfu10hmA61IMc9KWK2P4P2Ricv+ oKgQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date:dkim-signature; bh=Wlb7+zDcpe208lo8Gw20p3WJPZeydjxJEufXKINMMWc=; b=CbxlxNMTOKOODevZ6ctHOaazSwJEuHGZVrP6UYe7XeCCqQrfsgrNSUUhJ78QVEGs2R ozOQm1be2TFqcpOOwlrx1jK3JVR3ndwLTkRHdzPTjrpMFplWefcYbXuCumZO7dHUcy4j X8T26e7aUe/I+FhuJLdnCMixRHueYR0z0CzqF2DUGKadkukQHr7MsRtGKA1sTvfzkIvA zr8rqc4Rjqh734tOYWdiFiYKg9G/omPD8QCkun2xBpr+IP13gkgyu26bD8qgafUvb2vx ZwZRWqwdlCIOT7Ja1e8BJlY2uZlvzdd195/mZ3ew6RUTJb9z67b+pi87v0qZ75J4c93/ lgEQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=PN1TYpxt; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u63-v6si33194487pfb.172.2018.10.21.12.27.47; Sun, 21 Oct 2018 12:28:08 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=PN1TYpxt; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728196AbeJVDm3 (ORCPT + 99 others); Sun, 21 Oct 2018 23:42:29 -0400 Received: from mail.kernel.org ([198.145.29.99]:33384 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728069AbeJVDm3 (ORCPT ); Sun, 21 Oct 2018 23:42:29 -0400 Received: from earth.universe (unknown [62.214.5.194]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 9396B2083C; Sun, 21 Oct 2018 19:27:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1540150027; bh=wiQttENLXnk9hHEiXAptwf+UY40hE3B5VP57EAiFvEU=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=PN1TYpxt0y1eR8Madv7uRJYVZ7xVrBElopfeB23fXBlGyuWGg9nyssTmXDtyX20nI YQjHnueWMzJrGtbB01/g38ctBZTi+e5/DdrHoqTDIlUFCUhgw/f4ftFblQB50SJ1aI Ltb0AG1nE/p0RB2tdLxG84YNfj5lan8lCAfNUOvM= Received: by earth.universe (Postfix, from userid 1000) id 39C993C0995; Sun, 21 Oct 2018 18:26:29 +0200 (CEST) Date: Sun, 21 Oct 2018 18:26:29 +0200 From: Sebastian Reichel To: Baolin Wang Cc: robh+dt@kernel.org, mark.rutland@arm.com, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, yuanjiang.yu@unisoc.com, broonie@kernel.org, ctatlor97@gmail.com, linus.walleij@linaro.org Subject: Re: [PATCH v5 4/6] power: supply: core: Add some helpers to use the battery OCV capacity table Message-ID: <20181021162629.2rjsbqhmvx24cdno@earth.universe> References: MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="m7za4vanxjulrryw" Content-Disposition: inline In-Reply-To: User-Agent: NeoMutt/20180716 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org --m7za4vanxjulrryw Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hi, On Fri, Oct 19, 2018 at 06:53:13PM +0800, Baolin Wang wrote: > We have introduced some battery properties to present the OCV table > temperatures and OCV capacity table values. Thus this patch add OCV > temperature and OCV table for battery information, as well as providing > some helper functions to use the OCV capacity table for users. >=20 > Signed-off-by: Baolin Wang > Reviewed-by: Linus Walleij > --- Looks good to me. -- Sebastian > Changes from v4: > - None. >=20 > Changes from v3: > - Split core modification into one separate patch. > - Rename ocv-capacity-table-temperatures to ocv-capacity-celsius. >=20 > Changes from v2: > - Use type __be32 to calculate the table length. > - Update error messages. > - Add some helper functions. >=20 > Changes from v1: > - New patch in v2. > --- > drivers/power/supply/power_supply_core.c | 123 ++++++++++++++++++++++++= +++++- > include/linux/power_supply.h | 19 +++++ > 2 files changed, 141 insertions(+), 1 deletion(-) >=20 > diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/sup= ply/power_supply_core.c > index 307e0995..58c4309 100644 > --- a/drivers/power/supply/power_supply_core.c > +++ b/drivers/power/supply/power_supply_core.c > @@ -570,7 +570,7 @@ int power_supply_get_battery_info(struct power_supply= *psy, > { > struct device_node *battery_np; > const char *value; > - int err; > + int err, len, index; > =20 > info->energy_full_design_uwh =3D -EINVAL; > info->charge_full_design_uah =3D -EINVAL; > @@ -581,6 +581,12 @@ int power_supply_get_battery_info(struct power_suppl= y *psy, > info->constant_charge_voltage_max_uv =3D -EINVAL; > info->factory_internal_resistance_uohm =3D -EINVAL; > =20 > + for (index =3D 0; index < POWER_SUPPLY_OCV_TEMP_MAX; index++) { > + info->ocv_table[index] =3D NULL; > + info->ocv_temp[index] =3D -EINVAL; > + info->ocv_table_size[index] =3D -EINVAL; > + } > + > if (!psy->of_node) { > dev_warn(&psy->dev, "%s currently only supports devicetree\n", > __func__); > @@ -620,10 +626,125 @@ int power_supply_get_battery_info(struct power_sup= ply *psy, > of_property_read_u32(battery_np, "factory-internal-resistance-micro-ohm= s", > &info->factory_internal_resistance_uohm); > =20 > + len =3D of_property_count_u32_elems(battery_np, "ocv-capacity-celsius"); > + if (len < 0 && len !=3D -EINVAL) { > + return len; > + } else if (len > POWER_SUPPLY_OCV_TEMP_MAX) { > + dev_err(&psy->dev, "Too many temperature values\n"); > + return -EINVAL; > + } else if (len > 0) { > + of_property_read_u32_array(battery_np, "ocv-capacity-celsius", > + info->ocv_temp, len); > + } > + > + for (index =3D 0; index < len; index++) { > + struct power_supply_battery_ocv_table *table; > + char *propname; > + const __be32 *list; > + int i, tab_len, size; > + > + propname =3D kasprintf(GFP_KERNEL, "ocv-capacity-table-%d", index); > + list =3D of_get_property(battery_np, propname, &size); > + if (!list || !size) { > + dev_err(&psy->dev, "failed to get %s\n", propname); > + kfree(propname); > + power_supply_put_battery_info(psy, info); > + return -EINVAL; > + } > + > + kfree(propname); > + tab_len =3D size / (2 * sizeof(__be32)); > + info->ocv_table_size[index] =3D tab_len; > + > + table =3D info->ocv_table[index] =3D > + devm_kzalloc(&psy->dev, tab_len * sizeof(*table), > + GFP_KERNEL); > + if (!info->ocv_table[index]) { > + power_supply_put_battery_info(psy, info); > + return -ENOMEM; > + } > + > + for (i =3D 0; i < tab_len; i++) { > + table[i].ocv =3D be32_to_cpu(*list++); > + table[i].capacity =3D be32_to_cpu(*list++); > + } > + } > + > return 0; > } > EXPORT_SYMBOL_GPL(power_supply_get_battery_info); > =20 > +void power_supply_put_battery_info(struct power_supply *psy, > + struct power_supply_battery_info *info) > +{ > + int i; > + > + for (i =3D 0; i < POWER_SUPPLY_OCV_TEMP_MAX; i++) > + kfree(info->ocv_table[i]); > +} > +EXPORT_SYMBOL_GPL(power_supply_put_battery_info); > + > +int power_supply_ocv2cap_simple(struct power_supply_battery_ocv_table *t= able, > + int table_len, int ocv) > +{ > + int i, cap, tmp; > + > + for (i =3D 0; i < table_len; i++) > + if (ocv > table[i].ocv) > + break; > + > + if (i > 0 && i < table_len) { > + tmp =3D (table[i - 1].capacity - table[i].capacity) * > + (ocv - table[i].ocv); > + tmp /=3D table[i - 1].ocv - table[i].ocv; > + cap =3D tmp + table[i].capacity; > + } else if (i =3D=3D 0) { > + cap =3D table[0].capacity; > + } else { > + cap =3D table[table_len - 1].capacity; > + } > + > + return cap; > +} > +EXPORT_SYMBOL_GPL(power_supply_ocv2cap_simple); > + > +struct power_supply_battery_ocv_table * > +power_supply_find_ocv2cap_table(struct power_supply_battery_info *info, > + int temp, int *table_len) > +{ > + int best_temp_diff =3D INT_MAX, best_index =3D 0, temp_diff, i; > + > + if (!info->ocv_table[0]) > + return NULL; > + > + for (i =3D 0; i < POWER_SUPPLY_OCV_TEMP_MAX; i++) { > + temp_diff =3D abs(info->ocv_temp[i] - temp); > + > + if (temp_diff < best_temp_diff) { > + best_temp_diff =3D temp_diff; > + best_index =3D i; > + } > + } > + > + *table_len =3D info->ocv_table_size[best_index]; > + return info->ocv_table[best_index]; > +} > +EXPORT_SYMBOL_GPL(power_supply_find_ocv2cap_table); > + > +int power_supply_batinfo_ocv2cap(struct power_supply_battery_info *info, > + int ocv, int temp) > +{ > + struct power_supply_battery_ocv_table *table; > + int table_len; > + > + table =3D power_supply_find_ocv2cap_table(info, temp, &table_len); > + if (!table) > + return -EINVAL; > + > + return power_supply_ocv2cap_simple(table, table_len, ocv); > +} > +EXPORT_SYMBOL_GPL(power_supply_batinfo_ocv2cap); > + > int power_supply_get_property(struct power_supply *psy, > enum power_supply_property psp, > union power_supply_propval *val) > diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h > index d089566..84fe93f 100644 > --- a/include/linux/power_supply.h > +++ b/include/linux/power_supply.h > @@ -309,6 +309,13 @@ struct power_supply_info { > int use_for_apm; > }; > =20 > +struct power_supply_battery_ocv_table { > + int ocv; /* microVolts */ > + int capacity; /* percent */ > +}; > + > +#define POWER_SUPPLY_OCV_TEMP_MAX 20 > + > /* > * This is the recommended struct to manage static battery parameters, > * populated by power_supply_get_battery_info(). Most platform drivers s= hould > @@ -327,6 +334,9 @@ struct power_supply_battery_info { > int constant_charge_current_max_ua; /* microAmps */ > int constant_charge_voltage_max_uv; /* microVolts */ > int factory_internal_resistance_uohm; /* microOhms */ > + int ocv_temp[POWER_SUPPLY_OCV_TEMP_MAX];/* celsius */ > + struct power_supply_battery_ocv_table *ocv_table[POWER_SUPPLY_OCV_TEMP_= MAX]; > + int ocv_table_size[POWER_SUPPLY_OCV_TEMP_MAX]; > }; > =20 > extern struct atomic_notifier_head power_supply_notifier; > @@ -350,6 +360,15 @@ extern struct power_supply *devm_power_supply_get_by= _phandle( > =20 > extern int power_supply_get_battery_info(struct power_supply *psy, > struct power_supply_battery_info *info); > +extern void power_supply_put_battery_info(struct power_supply *psy, > + struct power_supply_battery_info *info); > +extern int power_supply_ocv2cap_simple(struct power_supply_battery_ocv_t= able *table, > + int table_len, int ocv); > +extern struct power_supply_battery_ocv_table * > +power_supply_find_ocv2cap_table(struct power_supply_battery_info *info, > + int temp, int *table_len); > +extern int power_supply_batinfo_ocv2cap(struct power_supply_battery_info= *info, > + int ocv, int temp); > extern void power_supply_changed(struct power_supply *psy); > extern int power_supply_am_i_supplied(struct power_supply *psy); > extern int power_supply_set_input_current_limit_from_supplier( > --=20 > 1.7.9.5 >=20 --m7za4vanxjulrryw Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIzBAEBCgAdFiEE72YNB0Y/i3JqeVQT2O7X88g7+poFAlvMqLUACgkQ2O7X88g7 +pqluA/7BpU6uBlgYBJ2XG7xV0Z7NBYNHGecHSO/Fvetd4KEmOFZLSNZL8pTXesf wXHqwXh9cXErtUoTlntMWDlqadauUKqUAJ0dr+kMqp3eWoCz+Ni7d/kAihpBT89t NtlPudBXVKspxiYVlosveOy64Kll7QjF6Lm6cjj/NSsoA31eH+MC1UzCiwX8Ar8S as7uuJr2a5Tp5jBRoFK+ss6o24brTthf/NLvcx7WzLTnTy+QZRHNRlcnqQ3c4Bgs gDFZZ2BT0QwTCQJ3z7pxB2AByJaO1KqDRlPofDohqm85CCIVKrkZke2/s9I7/A6D nn70WP7UpEKGXwXeAh4tyLWmOi6XxqHuGf+t1CgKCUf7cJ4+8uOGAyI+uZqOuymU CxPv0cKIgqUj2Cto/IhJPojyrZhtpw28A3/lLwPu+4CHMJaHawZaRh+gE9TpUekQ OqPjeicnR/GuLjuijoIp39nGHnBLrLMpKFjDtVifdM9H3MRT78x8TVGrdJbvaXYv zy4fdRjIkFL4feaqHNHcxF02rRZrdKMwl8JIkFrQ2weoF+jFKYQQ8z2Cy5OtXetr DVg5JytTrDa99IKWAatTs/mLBYVj18nXN+S1rq2UA9e678zgfHAuCrVd8xqAPqNP L8eHvBv32ASEej/P3oRdBDo6MG7PaeAJQrySUvOsAe76yIE2kbo= =tzMI -----END PGP SIGNATURE----- --m7za4vanxjulrryw--