forked from rubenslte/android_kernel_samsung_msm8226
of: batterydata: Introduce DT support for battery data
Add the of_batterydata driver to parse device tree battery data. Battery data contains battery profile information and is used by the charger and the BMS drivers. Change-Id: Ibe03800be0d51e82194c9385c6348c5a6c92711d Signed-off-by: Xiaozhe Shi <xiaozhes@codeaurora.org>
This commit is contained in:
@@ -0,0 +1,163 @@
|
||||
Battery Profile Data
|
||||
|
||||
Battery Data is a collection of battery profile data made available to
|
||||
the QPNP Charger and BMS drivers via device tree.
|
||||
|
||||
qcom,battery-data node required properties:
|
||||
- qcom,rpull-up-kohm : The vadc pullup resistor's resistance value in kOhms.
|
||||
- qcom,vref-batt-therm-uv : The vadc voltage used to make readings.
|
||||
For Qualcomm VADCs this should be 1800000uV.
|
||||
|
||||
qcom,battery-data can also include any number of children nodes. These children
|
||||
nodes will be treated as battery profile data nodes.
|
||||
|
||||
Profile data node required properties:
|
||||
- qcom,fcc-mah : Full charge count of the battery in milliamp-hours
|
||||
- qcom,default-rbatt-mohm : The nominal battery resistance value
|
||||
- qcom,rbatt-capacitive-mohm : The capacitive resistance of the battery.
|
||||
- qcom,flat-ocv-threshold-uv : The threshold under which the battery can be
|
||||
considered to be in the flat portion of the discharge
|
||||
curve.
|
||||
- qcom,max-voltage-uv : The maximum rated voltage of the battery
|
||||
- qcom,v-cutoff-uv : The cutoff voltage of the battery at which the device
|
||||
should shutdown gracefully.
|
||||
- qcom,chg-term-ua : The termination charging current of the battery.
|
||||
- qcom,batt-id-kohm : The battery id resistance of the battery.
|
||||
|
||||
Profile data node required subnodes:
|
||||
- qcom,fcc-temp-lut : An 1-dimensional lookup table node that encodes
|
||||
temperature to fcc lookup. The units for this lookup
|
||||
table should be degrees celsius to milliamp-hours.
|
||||
- qcom,pc-temp-ocv-lut : A 2-dimensional lookup table node that encodes
|
||||
temperature and percent charge to open circuit voltage
|
||||
lookup. The units for this lookup table should be
|
||||
degrees celsius and percent to millivolts.
|
||||
- qcom,rbatt-sf-lut : A 2-dimentional lookup table node that encodes
|
||||
temperature and percent charge to battery internal
|
||||
resistance lookup. The units for this lookup table
|
||||
should be degrees celsius and percent to milliohms.
|
||||
|
||||
Lookup table required properties:
|
||||
- qcom,lut-col-legend : An array that encodes the legend of the lookup table's
|
||||
columns. The length of this array will determine the
|
||||
lookup table's width.
|
||||
- qcom,lut-data : An array that encodes the lookup table's data. The size of this
|
||||
array should be equal to the size of qcom,lut-col-legend
|
||||
multiplied by 1 if it's a 1-dimensional table, or
|
||||
the size of qcom,lut-row-legend if it's a 2-dimensional
|
||||
table. The data should be in a flattened row-major
|
||||
representation.
|
||||
|
||||
Lookup table optional properties:
|
||||
- qcom,lut-row-legend : An array that encodes the legend of the lookup table's rows.
|
||||
If this property exists, then it is assumed that the
|
||||
lookup table is a 2-dimensional table.
|
||||
|
||||
Example:
|
||||
|
||||
In msm8974-mtp.dtsi:
|
||||
|
||||
mtp_batterydata: qcom,battery-data {
|
||||
qcom,rpull-up-kohm = <100>;
|
||||
qcom,vref-batt-therm-uv = <1800000>;
|
||||
|
||||
/include/ "batterydata-palladium.dtsi"
|
||||
/include/ "batterydata-mtp-3000mah.dtsi"
|
||||
};
|
||||
|
||||
&pm8941_bms {
|
||||
qcom,battery-data = <&mtp_batterydata>;
|
||||
};
|
||||
|
||||
In batterydata-palladium.dtsi:
|
||||
|
||||
qcom,palladium-batterydata {
|
||||
qcom,fcc-mah = <1500>;
|
||||
qcom,default-rbatt-mohm = <236>;
|
||||
qcom,rbatt-capacitive-mohm = <50>;
|
||||
qcom,flat-ocv-threshold-uv = <3800000>;
|
||||
qcom,max-voltage-uv = <4200000>;
|
||||
qcom,v-cutoff-uv = <3400000>;
|
||||
qcom,chg-term-ua = <100000>;
|
||||
qcom,batt-id-kohm = <75>;
|
||||
|
||||
qcom,fcc-temp-lut {
|
||||
qcom,lut-col-legend = <(-20) 0 25 40 65>;
|
||||
qcom,lut-data = <1492 1492 1493 1483 1502>;
|
||||
};
|
||||
|
||||
qcom,pc-temp-ocv-lut {
|
||||
qcom,lut-col-legend = <(-20) 0 25 40 65>;
|
||||
qcom,lut-row-legend = <100 95 90 85 80 75 70>,
|
||||
<65 60 55 50 45 40 35>,
|
||||
<30 25 20 15 10 9 8>,
|
||||
<7 6 5 4 3 2 1 0>;
|
||||
qcom,lut-data = <4173 4167 4163 4156 4154>,
|
||||
<4104 4107 4108 4102 4104>,
|
||||
<4057 4072 4069 4061 4060>,
|
||||
<3973 4009 4019 4016 4020>,
|
||||
<3932 3959 3981 3982 3983>,
|
||||
<3899 3928 3954 3950 3950>,
|
||||
<3868 3895 3925 3921 3920>,
|
||||
<3837 3866 3898 3894 3892>,
|
||||
<3812 3841 3853 3856 3862>,
|
||||
<3794 3818 3825 3823 3822>,
|
||||
<3780 3799 3804 3804 3803>,
|
||||
<3768 3787 3790 3788 3788>,
|
||||
<3757 3779 3778 3775 3776>,
|
||||
<3747 3772 3771 3766 3765>,
|
||||
<3736 3763 3766 3760 3746>,
|
||||
<3725 3749 3756 3747 3729>,
|
||||
<3714 3718 3734 3724 3706>,
|
||||
<3701 3703 3696 3689 3668>,
|
||||
<3675 3695 3682 3675 3662>,
|
||||
<3670 3691 3680 3673 3661>,
|
||||
<3661 3686 3679 3672 3656>,
|
||||
<3649 3680 3676 3669 3641>,
|
||||
<3633 3669 3667 3655 3606>,
|
||||
<3610 3647 3640 3620 3560>,
|
||||
<3580 3607 3596 3572 3501>,
|
||||
<3533 3548 3537 3512 3425>,
|
||||
<3457 3468 3459 3429 3324>,
|
||||
<3328 3348 3340 3297 3172>,
|
||||
<3000 3000 3000 3000 3000>;
|
||||
};
|
||||
|
||||
qcom,rbatt-sf-lut {
|
||||
qcom,lut-col-legend = <(-20) 0 25 40 65>;
|
||||
qcom,lut-row-legend = <100 95 90 85 80 75 70>,
|
||||
<65 60 55 50 45 40 35>,
|
||||
<30 25 20 15 10 9 8>,
|
||||
<7 6 5 4 3 2 1 0>;
|
||||
qcom,lut-data = <357 187 100 91 91>,
|
||||
<400 208 105 94 94>,
|
||||
<390 204 106 95 96>,
|
||||
<391 201 108 98 98>,
|
||||
<391 202 110 98 100>,
|
||||
<390 200 110 99 102>,
|
||||
<389 200 110 99 102>,
|
||||
<393 202 101 93 100>,
|
||||
<407 205 99 89 94>,
|
||||
<428 208 100 91 96>,
|
||||
<455 212 102 92 98>,
|
||||
<495 220 104 93 101>,
|
||||
<561 232 107 95 102>,
|
||||
<634 245 112 98 98>,
|
||||
<714 258 114 98 98>,
|
||||
<791 266 114 97 100>,
|
||||
<871 289 108 95 97>,
|
||||
<973 340 124 108 105>,
|
||||
<489 241 109 96 99>,
|
||||
<511 246 110 96 99>,
|
||||
<534 252 111 95 98>,
|
||||
<579 263 112 96 96>,
|
||||
<636 276 111 95 97>,
|
||||
<730 294 109 96 99>,
|
||||
<868 328 112 98 104>,
|
||||
<1089 374 119 101 115>,
|
||||
<1559 457 128 105 213>,
|
||||
<12886 1026 637 422 3269>,
|
||||
<170899 127211 98968 88907 77102>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -13,6 +13,11 @@ device is to enabled:
|
||||
to determine whether the BMS is using an internal or external
|
||||
rsense to accumulate the Coulomb Counter and read current.
|
||||
|
||||
Additionally, an optional subnode may be included:
|
||||
- qcom,battery-data : A phandle to a node containing the available batterydata
|
||||
profiles. See the batterydata bindings documentation for more
|
||||
details.
|
||||
|
||||
Parent node required properties:
|
||||
- compatible : should be "qcom,qpnp-bms" for the BM driver.
|
||||
- qcom,r-sense-uohm : sensor resistance in in micro-ohms.
|
||||
@@ -138,6 +143,7 @@ pm8941_bms: qcom,bms {
|
||||
qcom,high-ocv-correction-limit-uv = <50>;
|
||||
qcom,hold-soc-est = <3>;
|
||||
qcom,tm-temp-margin = <5000>;
|
||||
qcom,battery-data = <&mtp_batterydata>;
|
||||
|
||||
qcom,bms-iadc@3800 {
|
||||
reg = <0x3800 0x100>;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
@@ -13,7 +13,7 @@
|
||||
#define pr_fmt(fmt) "%s: " fmt, __func__
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/mfd/pm8xxx/batterydata-lib.h>
|
||||
#include <linux/batterydata-lib.h>
|
||||
|
||||
int linear_interpolate(int y0, int x0, int y1, int x1, int x)
|
||||
{
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/mfd/pm8xxx/batterydata-lib.h>
|
||||
#include <linux/batterydata-lib.h>
|
||||
|
||||
static struct single_row_lut desay_5200_fcc_temp = {
|
||||
.x = {-20, 0, 25, 40},
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/mfd/pm8xxx/batterydata-lib.h>
|
||||
#include <linux/batterydata-lib.h>
|
||||
|
||||
static struct single_row_lut fcc_temp = {
|
||||
.x = {-20, 0, 25, 40, 65},
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/mfd/pm8xxx/batterydata-lib.h>
|
||||
#include <linux/batterydata-lib.h>
|
||||
|
||||
static struct single_row_lut fcc_temp = {
|
||||
.x = {-20, 0, 25, 40, 60},
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
#include <linux/mfd/pm8xxx/batterydata-lib.h>
|
||||
#include <linux/batterydata-lib.h>
|
||||
|
||||
static struct single_row_lut fcc_temp = {
|
||||
.x = {-20, 0, 25, 40, 60},
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/mfd/pm8xxx/batterydata-lib.h>
|
||||
#include <linux/batterydata-lib.h>
|
||||
|
||||
static struct single_row_lut fcc_temp = {
|
||||
.x = {-20, 0, 25, 40, 65},
|
||||
|
||||
@@ -113,4 +113,9 @@ config OF_CORESIGHT
|
||||
help
|
||||
OpenFirmware CoreSight accessors
|
||||
|
||||
config OF_BATTERYDATA
|
||||
def_bool y
|
||||
help
|
||||
OpenFirmware BatteryData accessors
|
||||
|
||||
endmenu # OF
|
||||
|
||||
@@ -16,3 +16,4 @@ obj-$(CONFIG_OF_SPMI) += of_spmi.o
|
||||
obj-$(CONFIG_OF_MTD) += of_mtd.o
|
||||
obj-$(CONFIG_OF_SLIMBUS) += of_slimbus.o
|
||||
obj-$(CONFIG_OF_CORESIGHT) += of_coresight.o
|
||||
obj-$(CONFIG_OF_BATTERYDATA) += of_batterydata.o
|
||||
|
||||
@@ -0,0 +1,265 @@
|
||||
/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "%s: " fmt, __func__
|
||||
|
||||
#include <linux/of.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/batterydata-lib.h>
|
||||
|
||||
static int of_batterydata_read_lut(const struct device_node *np,
|
||||
int max_cols, int max_rows, int *ncols, int *nrows,
|
||||
int *col_legend_data, int *row_legend_data,
|
||||
int *lut_data)
|
||||
{
|
||||
struct property *prop;
|
||||
const __be32 *data;
|
||||
int cols, rows, size, i, j, *out_values;
|
||||
|
||||
prop = of_find_property(np, "qcom,lut-col-legend", NULL);
|
||||
if (!prop) {
|
||||
pr_err("%s: No col legend found\n", np->name);
|
||||
return -EINVAL;
|
||||
} else if (!prop->value) {
|
||||
pr_err("%s: No col legend value found, np->name\n", np->name);
|
||||
return -ENODATA;
|
||||
} else if (prop->length > max_cols * sizeof(int)) {
|
||||
pr_err("%s: Too many columns\n", np->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cols = prop->length/sizeof(int);
|
||||
*ncols = cols;
|
||||
data = prop->value;
|
||||
for (i = 0; i < cols; i++)
|
||||
*col_legend_data++ = be32_to_cpup(data++);
|
||||
|
||||
prop = of_find_property(np, "qcom,lut-row-legend", NULL);
|
||||
if (!prop || row_legend_data == NULL) {
|
||||
/* single row lut */
|
||||
rows = 1;
|
||||
} else if (!prop->value) {
|
||||
pr_err("%s: No row legend value found\n", np->name);
|
||||
return -ENODATA;
|
||||
} else if (prop->length > max_rows * sizeof(int)) {
|
||||
pr_err("%s: Too many rows\n", np->name);
|
||||
return -EINVAL;
|
||||
} else {
|
||||
rows = prop->length/sizeof(int);
|
||||
*nrows = rows;
|
||||
data = prop->value;
|
||||
for (i = 0; i < rows; i++)
|
||||
*row_legend_data++ = be32_to_cpup(data++);
|
||||
}
|
||||
|
||||
prop = of_find_property(np, "qcom,lut-data", NULL);
|
||||
data = prop->value;
|
||||
size = prop->length/sizeof(int);
|
||||
if (!prop || size != cols * rows) {
|
||||
pr_err("%s: data size mismatch, %dx%d != %d\n",
|
||||
np->name, cols, rows, size);
|
||||
return -EINVAL;
|
||||
}
|
||||
for (i = 0; i < rows; i++) {
|
||||
out_values = lut_data + (max_cols * i);
|
||||
for (j = 0; j < cols; j++) {
|
||||
*out_values++ = be32_to_cpup(data++);
|
||||
pr_debug("Value = %d\n", *(out_values-1));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int of_batterydata_read_sf_lut(struct device_node *data_node,
|
||||
const char *name, struct sf_lut *lut)
|
||||
{
|
||||
struct device_node *node = of_find_node_by_name(data_node, name);
|
||||
int rc;
|
||||
|
||||
if (!lut) {
|
||||
pr_debug("No lut provided, skipping\n");
|
||||
return 0;
|
||||
} else if (!node) {
|
||||
pr_err("Couldn't find %s node.\n", name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = of_batterydata_read_lut(node, PC_CC_COLS, PC_CC_ROWS,
|
||||
&lut->cols, &lut->rows, lut->row_entries,
|
||||
lut->percent, *lut->sf);
|
||||
if (rc) {
|
||||
pr_err("Failed to read %s node.\n", name);
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int of_batterydata_read_pc_temp_ocv_lut(struct device_node *data_node,
|
||||
const char *name, struct pc_temp_ocv_lut *lut)
|
||||
{
|
||||
struct device_node *node = of_find_node_by_name(data_node, name);
|
||||
int rc;
|
||||
|
||||
if (!lut) {
|
||||
pr_debug("No lut provided, skipping\n");
|
||||
return 0;
|
||||
} else if (!node) {
|
||||
pr_err("Couldn't find %s node.\n", name);
|
||||
return -EINVAL;
|
||||
}
|
||||
rc = of_batterydata_read_lut(node, PC_TEMP_COLS, PC_TEMP_ROWS,
|
||||
&lut->cols, &lut->rows, lut->temp, lut->percent,
|
||||
*lut->ocv);
|
||||
if (rc) {
|
||||
pr_err("Failed to read %s node.\n", name);
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int of_batterydata_read_single_row_lut(struct device_node *data_node,
|
||||
const char *name, struct single_row_lut *lut)
|
||||
{
|
||||
struct device_node *node = of_find_node_by_name(data_node, name);
|
||||
int rc;
|
||||
|
||||
if (!lut) {
|
||||
pr_debug("No lut provided, skipping\n");
|
||||
return 0;
|
||||
} else if (!node) {
|
||||
pr_err("Couldn't find %s node.\n", name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = of_batterydata_read_lut(node, MAX_SINGLE_LUT_COLS, 1,
|
||||
&lut->cols, NULL, lut->x, NULL, lut->y);
|
||||
if (rc) {
|
||||
pr_err("Failed to read %s node.\n", name);
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define OF_PROP_READ(property, qpnp_dt_property, node, rc, optional) \
|
||||
do { \
|
||||
rc = of_property_read_u32(node, "qcom," qpnp_dt_property, \
|
||||
&property); \
|
||||
\
|
||||
if ((rc == -EINVAL) && optional) { \
|
||||
property = -EINVAL; \
|
||||
rc = 0; \
|
||||
} else if (rc) { \
|
||||
pr_err("Error reading " #qpnp_dt_property \
|
||||
" property rc = %d\n", rc); \
|
||||
return rc; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static int of_batterydata_load_battery_data(struct device_node *node,
|
||||
struct bms_battery_data *batt_data)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = of_batterydata_read_single_row_lut(node, "qcom,fcc-temp-lut",
|
||||
batt_data->fcc_temp_lut);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = of_batterydata_read_pc_temp_ocv_lut(node,
|
||||
"qcom,pc-temp-ocv-lut",
|
||||
batt_data->pc_temp_ocv_lut);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = of_batterydata_read_sf_lut(node, "qcom,rbatt-sf-lut",
|
||||
batt_data->rbatt_sf_lut);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
OF_PROP_READ(batt_data->fcc, "fcc-mah", node, rc, false);
|
||||
OF_PROP_READ(batt_data->default_rbatt_mohm,
|
||||
"default-rbatt-mohm", node, rc, false);
|
||||
OF_PROP_READ(batt_data->rbatt_capacitive_mohm,
|
||||
"rbatt-capacitive-mohm", node, rc, false);
|
||||
OF_PROP_READ(batt_data->batt_id_kohm, "batt-id-kohm", node, rc, false);
|
||||
OF_PROP_READ(batt_data->flat_ocv_threshold_uv,
|
||||
"flat-ocv-threshold", node, rc, true);
|
||||
OF_PROP_READ(batt_data->max_voltage_uv,
|
||||
"max-voltage-uv", node, rc, true);
|
||||
OF_PROP_READ(batt_data->cutoff_uv, "v-cutoff-uv", node, rc, true);
|
||||
OF_PROP_READ(batt_data->iterm_ua, "chg-term-ua", node, rc, true);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int64_t of_batterydata_convert_battery_id_kohm(int batt_id_uv,
|
||||
int rpull_up, int vadc_vdd)
|
||||
{
|
||||
int64_t resistor_value_kohm, denom;
|
||||
|
||||
/* calculate the battery id resistance reported via ADC */
|
||||
denom = div64_s64(vadc_vdd * 1000000LL, batt_id_uv) - 1000000LL;
|
||||
|
||||
resistor_value_kohm = div64_s64(rpull_up * 1000000LL + denom/2, denom);
|
||||
|
||||
pr_debug("batt id voltage = %d, resistor value = %lld\n",
|
||||
batt_id_uv, resistor_value_kohm);
|
||||
|
||||
return resistor_value_kohm;
|
||||
}
|
||||
|
||||
int of_batterydata_read_data(struct device_node *batterydata_container_node,
|
||||
struct bms_battery_data *batt_data,
|
||||
int batt_id_uv)
|
||||
{
|
||||
struct device_node *node, *best_node;
|
||||
uint32_t id_kohm;
|
||||
int delta, best_delta, batt_id_kohm, rpull_up_kohm, vadc_vdd_uv, rc = 0;
|
||||
|
||||
node = batterydata_container_node;
|
||||
OF_PROP_READ(rpull_up_kohm, "rpull-up-kohm", node, rc, false);
|
||||
OF_PROP_READ(vadc_vdd_uv, "vref-batt-therm", node, rc, false);
|
||||
|
||||
batt_id_kohm = of_batterydata_convert_battery_id_kohm(batt_id_uv,
|
||||
rpull_up_kohm, vadc_vdd_uv);
|
||||
best_node = NULL;
|
||||
best_delta = 0;
|
||||
|
||||
/*
|
||||
* Find the battery data with a battery id resistor closest to this one
|
||||
*/
|
||||
for_each_child_of_node(batterydata_container_node, node) {
|
||||
rc = of_property_read_u32(node, "qcom,batt-id-kohm", &id_kohm);
|
||||
if (rc)
|
||||
continue;
|
||||
delta = abs((int)id_kohm - batt_id_kohm);
|
||||
if (delta < best_delta || !best_node) {
|
||||
best_node = node;
|
||||
best_delta = delta;
|
||||
}
|
||||
}
|
||||
|
||||
if (best_node == NULL) {
|
||||
pr_err("No battery data found\n");
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
return of_batterydata_load_battery_data(best_node, batt_data);
|
||||
}
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
@@ -22,8 +22,8 @@
|
||||
#include <linux/mfd/pm8xxx/pm8xxx-adc.h>
|
||||
#include <linux/mfd/pm8xxx/pm8921-charger.h>
|
||||
#include <linux/mfd/pm8xxx/ccadc.h>
|
||||
#include <linux/mfd/pm8xxx/batterydata-lib.h>
|
||||
#include <linux/mfd/pm8xxx/batt-alarm.h>
|
||||
#include <linux/batterydata-lib.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/debugfs.h>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/qpnp/qpnp-adc.h>
|
||||
#include <linux/qpnp/power-on.h>
|
||||
#include <linux/mfd/pm8xxx/batterydata-lib.h>
|
||||
#include <linux/batterydata-lib.h>
|
||||
|
||||
/* BMS Register Offsets */
|
||||
#define BMS1_REVISION1 0x0
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __PM8XXX_BMS_BATTERYDATA_H
|
||||
#define __PM8XXX_BMS_BATTERYDATA_H
|
||||
#ifndef __BMS_BATTERYDATA_H
|
||||
#define __BMS_BATTERYDATA_H
|
||||
|
||||
#include <linux/errno.h>
|
||||
|
||||
@@ -95,6 +95,11 @@ enum battery_type {
|
||||
* battery capacitance
|
||||
* @flat_ocv_threshold_uv: the voltage where the battery's discharge curve
|
||||
* starts flattening out.
|
||||
* @max_voltage_uv: max voltage of the battery
|
||||
* @cutoff_uv: cutoff voltage of the battery
|
||||
* @iterm_ua: termination current of the battery when charging
|
||||
* to 100%
|
||||
* @batt_id_kohm: battery id resistor value
|
||||
*/
|
||||
|
||||
struct bms_battery_data {
|
||||
@@ -108,6 +113,10 @@ struct bms_battery_data {
|
||||
int delta_rbatt_mohm;
|
||||
int rbatt_capacitive_mohm;
|
||||
int flat_ocv_threshold_uv;
|
||||
int max_voltage_uv;
|
||||
int cutoff_uv;
|
||||
int iterm_ua;
|
||||
int batt_id_kohm;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_PM8921_BMS) || \
|
||||
@@ -14,7 +14,7 @@
|
||||
#define __PM8XXX_BMS_H
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/mfd/pm8xxx/batterydata-lib.h>
|
||||
#include <linux/batterydata-lib.h>
|
||||
|
||||
#define PM8921_BMS_DEV_NAME "pm8921-bms"
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/of.h>
|
||||
#include <linux/batterydata-lib.h>
|
||||
|
||||
#ifdef CONFIG_OF_BATTERYDATA
|
||||
/**
|
||||
* of_batterydata_read_data() - Populate battery data from the device tree
|
||||
* @container_node: pointer to the battery-data container device node
|
||||
* containing the profile nodes.
|
||||
* @batt_data: pointer to an allocated bms_battery_data structure that the
|
||||
* loaded profile will be written to.
|
||||
* @batt_id_uv: ADC voltage of the battery id line used to differentiate
|
||||
* between different battery profiles. If there are multiple
|
||||
* battery data in the device tree, the one with the closest
|
||||
* battery id resistance will be automatically loaded.
|
||||
*
|
||||
* This routine loads the closest match battery data from device tree based on
|
||||
* the battery id reading. Then, it will try to load all the relevant data from
|
||||
* the device tree battery data profile.
|
||||
*
|
||||
* If any of the lookup table pointers are NULL, this routine will skip trying
|
||||
* to read them.
|
||||
*/
|
||||
int of_batterydata_read_data(struct device_node *container_node,
|
||||
struct bms_battery_data *batt_data,
|
||||
int batt_id_uv);
|
||||
#else
|
||||
static inline int of_batterydata_read_data(struct device_node *container_node,
|
||||
struct bms_battery_data *batt_data,
|
||||
int batt_id_uv);
|
||||
{
|
||||
return -ENXIO;
|
||||
}
|
||||
#endif /* CONFIG_OF_QPNP */
|
||||
Reference in New Issue
Block a user