msm: power: update power drivers to msm-3.4 tip
This branch is currently very outdated. Cherry pick the following changes in order to bring recent fixes to this branch. Change-Ids Ib99cd49623698d0295bc3c3cf880225495d530cb Ifba2bd1248e8bb47a0700dec4d321d32db4f2066 I0fc1e116c0f5a5648f99df967bdbb41fe5a07cbc I8e3e9068e7b9a3bfd24c07a00bb3953180ce0741 I2bf31a23199f942a9ac843b9940a0f7377256238 I96b47c8603a291c41c5769fab9483d83fefb6084 If3c5f00f4b75d03838ee556235697369fd2e47dd I32d50caf7b7a84db2654b69baafb40a441f46bf0 Ibd1020113de05e8214d41ffb975d4c95d3bb1ccf I67c2ac422b0ba1e5eca11ffccfe7e112c2e65a3d I2c149e6edd7c194e7f31ece95e2003ffde935806 I1f4b65cba149480fb4a8f91667ce45a876dff2f0 I2605afc2d6f9f3569ec783b2d23881f31cc9038a I77b40f9cb8295cff1d4a24dfc7d85b0e57262f6e I8ec5a68cad573218a0b0bd0073277b76978417ff I9eaf7f21c73dd1ceaf97589cbf82b722706c48c2 I089725e20ae20956530e570d918a87b72e59626e Ifa70a4daf01414dfafed7830e3a6a682c42e9364 Iaace5bc1d0611619f11b760ea6986eadb7346da1 I415d7831f15c0d690fd118ff190cd710a31368c6 I1e55bbfe37c7cc6f62581af11280a565ed648c06 I11938c569a25b026ee6b7b5125cec930676ec01d I07577d1aa57bfa4bee40b52c18b5bfcb1cdb7070 Icdb0a28b5f9456135c60badf726c367b02f6d762 I4f14b7419f7a90813650601638f6563422c13ae4 I016a33c358be2e7a2d26202f2e9b168dd54b6d34 I43e26a2932ab3e3d9d79bb5af7daf2364ca133b7 I333c810568cdc656d2e13f0eeb9511857335b834 I830bf2e679e76efe7ed9d8bb30a8d459d8b9a09a I08d8d319d096c050ae53d90eeac293c9b1bab2bf I445676d558e05a6c5e9dd1e76e80ba2f5e8cd6c1 I9f38515f35fcddfbdc34ae4f59ffcfc6682033d4 Ia32e581c11954163bc8ff20a7b32432a843a17b2 I07c346475fb4a294bc8eb8da8c2048cc23394e20 Ic3f2c4e5bafd3a1556412005564fc0b549e6813c Ic68717f4410170814d3e3b141de77b35eca12f7b Ifad79991298e9d779b38a33a270af5197d2fc060 I3060c5ba31b59666aedfafad430e21329c4479d4 I9c87282ba5819a76a6f6697a5e9de6c92d74a665 I8144e2b83748a96ab83ba14894bfa5bd59995895 I8cac84296ddb1e323f28e2476f78d0190f4a1b73 Icef2b7fa70f274f671bd1b9469eb6a333ab462f9 Idc4ceb7973d1a424834f8c2a4bc5916ef7b1e961 I1bc779e5890f6994442c562ee5abf37c06dc6d3d Ib1161d3d8c4a9378eabf44f9de1eae9556d82643 I11a17fc105dea398140abc1a59e6355e9e55b322 I0aa523321f1eed4a0a5461b1a894452f77e6ff99 I827bd74e9892969bb4891b31af1515789fa76c1c I1bb658339e5a6f0adb07fda3ee0bc6c03670cc09 I135261c851067a25b20b30482764b5a61145f186 I4971d605c3475949be64372dc6bd3355ed258527 I08f6a7830c4b9ad44fb96f6d304ce257a899e287 I96886f8d0f3f03905163d93c4f8f3e637d98127f Idf2cf7f40780cf46ba95228764790b818bc72db5 Ib046fd7149d71fc62c8f2df7a9747d6b54e95138 I546ff57d76e50ad86eb5853782fdcc1f348c9f0e I1293ecc2974bae4ad530ecb775cd19072e413c72 I8db5a202a2e63ca0a3e355a6083d426acb7342cb I71482f9a4430a8bbcd02c954a415ff3fab2a0c8f I0c5656798444764b52f4d9d8889f831d674a1610 I2ac4ccd967a7a47284573c9b645055ebeca4635c I93b830d42e7d44435c790832c11d5d38861015e0 If24985f47cc9fcd6c2eb84a73165878559008120 I39b908451f4b678ed63b872ffc46590e2c728b2c If7e5622067c77c4c8d64ee466d1c62e4dcb0e53f If58279329f6c76978223369a2d08d47a7b1e3579 I3621a0a204360343ba684e2217a68a6ef51a7850 I358909c38b0771fe0283386841b6123ddb2931a6 I2e8fcb4a15af3a66331a921d378bfd5d2dfe4533 I0bbad22c5fed8c32dd7de387194e94c8d4b9ad75 I34f51c6202cbaa805c496360e8dbd391890decc6 Iaab82ea254444bba233cd9ebad93d38426154ca4 Ica2565031546a8281820c17edc95d258ad31ba65 Ic282fff7167a8224ec1a1e0f7c247a9c8d73f390 Icdc707a9438adae5c8bb2d9b97af95e65c4bc2a1 I26c4e1fb971f22ec721e1dddcce6b301f5db6608 I8882575084eefa6a23bd59b8d2a54a53d793298e Ic1e7cf4da4d2bf73d889aee7bac6cf260b26d532 I472b9da10e9f45b3c254f8440526f3f9d5116931 I1560e0df1c89be1db1e1d1aeaaeef2e6da5f85c1 Ie2842b28648084d8970329d7c76fcf0d0666a847 I2dccaedb559fc5e9865b137f980024e068bdafa3 I61a3d44f81d829f1ef22fd3044c65e4b3518b92b I0d657c2e0d47af32cc35cd66b902be72952e5438 I22d2dbdae5c9c859d4baca2bdb7bea71da09b85b I8c99fcbbf2f7229728236ae1059f4c9cb8dbb065 I1bb841e463658c8db42eb15ecc1687262df86a2f Change-Id: Ib04f801b0085e7d5da3d73594bbc41c281b06026 Signed-off-by: Xiaozhe Shi <xiaozhes@codeaurora.org>
This commit is contained in:
committed by
Stephen Boyd
parent
2f24cb771c
commit
fae0afd7be
@@ -280,7 +280,7 @@ obj-$(CONFIG_MACH_MSM8960_FLUID) += board-8960-all.o board-8960-regulator.o
|
||||
obj-$(CONFIG_MACH_MSM8930_CDP) += board-8930-all.o board-8930-regulator-pm8038.o board-8930-regulator-pm8917.o
|
||||
obj-$(CONFIG_MACH_MSM8930_MTP) += board-8930-all.o board-8930-regulator-pm8038.o board-8930-regulator-pm8917.o
|
||||
obj-$(CONFIG_MACH_MSM8930_FLUID) += board-8930-all.o board-8930-regulator-pm8038.o board-8930-regulator-pm8917.o
|
||||
obj-$(CONFIG_PM8921_BMS) += bms-batterydata.o bms-batterydata-desay.o
|
||||
obj-$(CONFIG_PM8921_BMS) += bms-batterydata.o bms-batterydata-desay.o batterydata-lib.o
|
||||
obj-$(CONFIG_MACH_APQ8064_CDP) += board-8064-all.o board-8064-regulator.o
|
||||
obj-$(CONFIG_MACH_APQ8064_MTP) += board-8064-all.o board-8064-regulator.o
|
||||
obj-$(CONFIG_MACH_APQ8064_LIQUID) += board-8064-all.o board-8064-regulator.o
|
||||
|
||||
338
arch/arm/mach-msm/batterydata-lib.c
Normal file
338
arch/arm/mach-msm/batterydata-lib.c
Normal file
@@ -0,0 +1,338 @@
|
||||
/* Copyright (c) 2012, 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/module.h>
|
||||
#include <linux/mfd/pm8xxx/batterydata-lib.h>
|
||||
|
||||
int linear_interpolate(int y0, int x0, int y1, int x1, int x)
|
||||
{
|
||||
if (y0 == y1 || x == x0)
|
||||
return y0;
|
||||
if (x1 == x0 || x == x1)
|
||||
return y1;
|
||||
|
||||
return y0 + ((y1 - y0) * (x - x0) / (x1 - x0));
|
||||
}
|
||||
|
||||
int is_between(int left, int right, int value)
|
||||
{
|
||||
if (left >= right && left >= value && value >= right)
|
||||
return 1;
|
||||
if (left <= right && left <= value && value <= right)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int interpolate_single_lut(struct single_row_lut *lut, int x)
|
||||
{
|
||||
int i, result;
|
||||
|
||||
if (x < lut->x[0]) {
|
||||
pr_debug("x %d less than known range return y = %d lut = %pS\n",
|
||||
x, lut->y[0], lut);
|
||||
return lut->y[0];
|
||||
}
|
||||
if (x > lut->x[lut->cols - 1]) {
|
||||
pr_debug("x %d more than known range return y = %d lut = %pS\n",
|
||||
x, lut->y[lut->cols - 1], lut);
|
||||
return lut->y[lut->cols - 1];
|
||||
}
|
||||
|
||||
for (i = 0; i < lut->cols; i++)
|
||||
if (x <= lut->x[i])
|
||||
break;
|
||||
if (x == lut->x[i]) {
|
||||
result = lut->y[i];
|
||||
} else {
|
||||
result = linear_interpolate(
|
||||
lut->y[i - 1],
|
||||
lut->x[i - 1],
|
||||
lut->y[i],
|
||||
lut->x[i],
|
||||
x);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int interpolate_fcc(struct single_row_lut *fcc_temp_lut, int batt_temp)
|
||||
{
|
||||
/* batt_temp is in tenths of degC - convert it to degC for lookups */
|
||||
batt_temp = batt_temp/10;
|
||||
return interpolate_single_lut(fcc_temp_lut, batt_temp);
|
||||
}
|
||||
|
||||
int interpolate_scalingfactor_fcc(struct single_row_lut *fcc_sf_lut,
|
||||
int cycles)
|
||||
{
|
||||
/*
|
||||
* sf table could be null when no battery aging data is available, in
|
||||
* that case return 100%
|
||||
*/
|
||||
if (fcc_sf_lut)
|
||||
return interpolate_single_lut(fcc_sf_lut, cycles);
|
||||
else
|
||||
return 100;
|
||||
}
|
||||
|
||||
int interpolate_scalingfactor(struct sf_lut *sf_lut, int row_entry, int pc)
|
||||
{
|
||||
int i, scalefactorrow1, scalefactorrow2, scalefactor, rows, cols;
|
||||
int row1 = 0;
|
||||
int row2 = 0;
|
||||
|
||||
/*
|
||||
* sf table could be null when no battery aging data is available, in
|
||||
* that case return 100%
|
||||
*/
|
||||
if (!sf_lut)
|
||||
return 100;
|
||||
|
||||
rows = sf_lut->rows;
|
||||
cols = sf_lut->cols;
|
||||
if (pc > sf_lut->percent[0]) {
|
||||
pr_debug("pc %d greater than known pc ranges for sfd\n", pc);
|
||||
row1 = 0;
|
||||
row2 = 0;
|
||||
}
|
||||
if (pc < sf_lut->percent[rows - 1]) {
|
||||
pr_debug("pc %d less than known pc ranges for sf\n", pc);
|
||||
row1 = rows - 1;
|
||||
row2 = rows - 1;
|
||||
}
|
||||
for (i = 0; i < rows; i++) {
|
||||
if (pc == sf_lut->percent[i]) {
|
||||
row1 = i;
|
||||
row2 = i;
|
||||
break;
|
||||
}
|
||||
if (pc > sf_lut->percent[i]) {
|
||||
row1 = i - 1;
|
||||
row2 = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (row_entry < sf_lut->row_entries[0])
|
||||
row_entry = sf_lut->row_entries[0];
|
||||
if (row_entry > sf_lut->row_entries[cols - 1])
|
||||
row_entry = sf_lut->row_entries[cols - 1];
|
||||
|
||||
for (i = 0; i < cols; i++)
|
||||
if (row_entry <= sf_lut->row_entries[i])
|
||||
break;
|
||||
if (row_entry == sf_lut->row_entries[i]) {
|
||||
scalefactor = linear_interpolate(
|
||||
sf_lut->sf[row1][i],
|
||||
sf_lut->percent[row1],
|
||||
sf_lut->sf[row2][i],
|
||||
sf_lut->percent[row2],
|
||||
pc);
|
||||
return scalefactor;
|
||||
}
|
||||
|
||||
scalefactorrow1 = linear_interpolate(
|
||||
sf_lut->sf[row1][i - 1],
|
||||
sf_lut->row_entries[i - 1],
|
||||
sf_lut->sf[row1][i],
|
||||
sf_lut->row_entries[i],
|
||||
row_entry);
|
||||
|
||||
scalefactorrow2 = linear_interpolate(
|
||||
sf_lut->sf[row2][i - 1],
|
||||
sf_lut->row_entries[i - 1],
|
||||
sf_lut->sf[row2][i],
|
||||
sf_lut->row_entries[i],
|
||||
row_entry);
|
||||
|
||||
scalefactor = linear_interpolate(
|
||||
scalefactorrow1,
|
||||
sf_lut->percent[row1],
|
||||
scalefactorrow2,
|
||||
sf_lut->percent[row2],
|
||||
pc);
|
||||
|
||||
return scalefactor;
|
||||
}
|
||||
|
||||
/* get ocv given a soc -- reverse lookup */
|
||||
int interpolate_ocv(struct pc_temp_ocv_lut *pc_temp_ocv,
|
||||
int batt_temp_degc, int pc)
|
||||
{
|
||||
int i, ocvrow1, ocvrow2, ocv, rows, cols;
|
||||
int row1 = 0;
|
||||
int row2 = 0;
|
||||
|
||||
rows = pc_temp_ocv->rows;
|
||||
cols = pc_temp_ocv->cols;
|
||||
if (pc > pc_temp_ocv->percent[0]) {
|
||||
pr_debug("pc %d greater than known pc ranges for sfd\n", pc);
|
||||
row1 = 0;
|
||||
row2 = 0;
|
||||
}
|
||||
if (pc < pc_temp_ocv->percent[rows - 1]) {
|
||||
pr_debug("pc %d less than known pc ranges for sf\n", pc);
|
||||
row1 = rows - 1;
|
||||
row2 = rows - 1;
|
||||
}
|
||||
for (i = 0; i < rows; i++) {
|
||||
if (pc == pc_temp_ocv->percent[i]) {
|
||||
row1 = i;
|
||||
row2 = i;
|
||||
break;
|
||||
}
|
||||
if (pc > pc_temp_ocv->percent[i]) {
|
||||
row1 = i - 1;
|
||||
row2 = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (batt_temp_degc < pc_temp_ocv->temp[0])
|
||||
batt_temp_degc = pc_temp_ocv->temp[0];
|
||||
if (batt_temp_degc > pc_temp_ocv->temp[cols - 1])
|
||||
batt_temp_degc = pc_temp_ocv->temp[cols - 1];
|
||||
|
||||
for (i = 0; i < cols; i++)
|
||||
if (batt_temp_degc <= pc_temp_ocv->temp[i])
|
||||
break;
|
||||
if (batt_temp_degc == pc_temp_ocv->temp[i]) {
|
||||
ocv = linear_interpolate(
|
||||
pc_temp_ocv->ocv[row1][i],
|
||||
pc_temp_ocv->percent[row1],
|
||||
pc_temp_ocv->ocv[row2][i],
|
||||
pc_temp_ocv->percent[row2],
|
||||
pc);
|
||||
return ocv;
|
||||
}
|
||||
|
||||
ocvrow1 = linear_interpolate(
|
||||
pc_temp_ocv->ocv[row1][i - 1],
|
||||
pc_temp_ocv->temp[i - 1],
|
||||
pc_temp_ocv->ocv[row1][i],
|
||||
pc_temp_ocv->temp[i],
|
||||
batt_temp_degc);
|
||||
|
||||
ocvrow2 = linear_interpolate(
|
||||
pc_temp_ocv->ocv[row2][i - 1],
|
||||
pc_temp_ocv->temp[i - 1],
|
||||
pc_temp_ocv->ocv[row2][i],
|
||||
pc_temp_ocv->temp[i],
|
||||
batt_temp_degc);
|
||||
|
||||
ocv = linear_interpolate(
|
||||
ocvrow1,
|
||||
pc_temp_ocv->percent[row1],
|
||||
ocvrow2,
|
||||
pc_temp_ocv->percent[row2],
|
||||
pc);
|
||||
|
||||
return ocv;
|
||||
}
|
||||
|
||||
int interpolate_pc(struct pc_temp_ocv_lut *pc_temp_ocv,
|
||||
int batt_temp_degc, int ocv)
|
||||
{
|
||||
int i, j, pcj, pcj_minus_one, pc;
|
||||
int rows = pc_temp_ocv->rows;
|
||||
int cols = pc_temp_ocv->cols;
|
||||
|
||||
if (batt_temp_degc < pc_temp_ocv->temp[0]) {
|
||||
pr_debug("batt_temp %d < known temp range\n", batt_temp_degc);
|
||||
batt_temp_degc = pc_temp_ocv->temp[0];
|
||||
}
|
||||
|
||||
if (batt_temp_degc > pc_temp_ocv->temp[cols - 1]) {
|
||||
pr_debug("batt_temp %d > known temp range\n", batt_temp_degc);
|
||||
batt_temp_degc = pc_temp_ocv->temp[cols - 1];
|
||||
}
|
||||
|
||||
for (j = 0; j < cols; j++)
|
||||
if (batt_temp_degc <= pc_temp_ocv->temp[j])
|
||||
break;
|
||||
if (batt_temp_degc == pc_temp_ocv->temp[j]) {
|
||||
/* found an exact match for temp in the table */
|
||||
if (ocv >= pc_temp_ocv->ocv[0][j])
|
||||
return pc_temp_ocv->percent[0];
|
||||
if (ocv <= pc_temp_ocv->ocv[rows - 1][j])
|
||||
return pc_temp_ocv->percent[rows - 1];
|
||||
for (i = 0; i < rows; i++) {
|
||||
if (ocv >= pc_temp_ocv->ocv[i][j]) {
|
||||
if (ocv == pc_temp_ocv->ocv[i][j])
|
||||
return pc_temp_ocv->percent[i];
|
||||
pc = linear_interpolate(
|
||||
pc_temp_ocv->percent[i],
|
||||
pc_temp_ocv->ocv[i][j],
|
||||
pc_temp_ocv->percent[i - 1],
|
||||
pc_temp_ocv->ocv[i - 1][j],
|
||||
ocv);
|
||||
return pc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* batt_temp_degc is within temperature for
|
||||
* column j-1 and j
|
||||
*/
|
||||
if (ocv >= pc_temp_ocv->ocv[0][j])
|
||||
return pc_temp_ocv->percent[0];
|
||||
if (ocv <= pc_temp_ocv->ocv[rows - 1][j - 1])
|
||||
return pc_temp_ocv->percent[rows - 1];
|
||||
|
||||
pcj_minus_one = 0;
|
||||
pcj = 0;
|
||||
for (i = 0; i < rows-1; i++) {
|
||||
if (pcj == 0
|
||||
&& is_between(pc_temp_ocv->ocv[i][j],
|
||||
pc_temp_ocv->ocv[i+1][j], ocv)) {
|
||||
pcj = linear_interpolate(
|
||||
pc_temp_ocv->percent[i],
|
||||
pc_temp_ocv->ocv[i][j],
|
||||
pc_temp_ocv->percent[i + 1],
|
||||
pc_temp_ocv->ocv[i+1][j],
|
||||
ocv);
|
||||
}
|
||||
|
||||
if (pcj_minus_one == 0
|
||||
&& is_between(pc_temp_ocv->ocv[i][j-1],
|
||||
pc_temp_ocv->ocv[i+1][j-1], ocv)) {
|
||||
pcj_minus_one = linear_interpolate(
|
||||
pc_temp_ocv->percent[i],
|
||||
pc_temp_ocv->ocv[i][j-1],
|
||||
pc_temp_ocv->percent[i + 1],
|
||||
pc_temp_ocv->ocv[i+1][j-1],
|
||||
ocv);
|
||||
}
|
||||
|
||||
if (pcj && pcj_minus_one) {
|
||||
pc = linear_interpolate(
|
||||
pcj_minus_one,
|
||||
pc_temp_ocv->temp[j-1],
|
||||
pcj,
|
||||
pc_temp_ocv->temp[j],
|
||||
batt_temp_degc);
|
||||
return pc;
|
||||
}
|
||||
}
|
||||
|
||||
if (pcj)
|
||||
return pcj;
|
||||
|
||||
if (pcj_minus_one)
|
||||
return pcj_minus_one;
|
||||
|
||||
pr_debug("%d ocv wasn't found for temp %d in the LUT returning 100%%\n",
|
||||
ocv, batt_temp_degc);
|
||||
return 100;
|
||||
}
|
||||
@@ -10,7 +10,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/mfd/pm8xxx/pm8921-bms.h>
|
||||
#include <linux/mfd/pm8xxx/batterydata-lib.h>
|
||||
|
||||
static struct single_row_lut desay_5200_fcc_temp = {
|
||||
.x = {-20, 0, 25, 40},
|
||||
@@ -76,7 +76,7 @@ static struct sf_lut desay_5200_pc_sf = {
|
||||
},
|
||||
};
|
||||
|
||||
struct pm8921_bms_battery_data desay_5200_data = {
|
||||
struct bms_battery_data desay_5200_data = {
|
||||
.fcc = 5200,
|
||||
.fcc_temp_lut = &desay_5200_fcc_temp,
|
||||
.fcc_sf_lut = &desay_5200_fcc_sf,
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/mfd/pm8xxx/pm8921-bms.h>
|
||||
#include <linux/mfd/pm8xxx/batterydata-lib.h>
|
||||
|
||||
static struct single_row_lut fcc_temp = {
|
||||
.x = {-20, 0, 25, 40, 65},
|
||||
@@ -99,7 +99,7 @@ static struct sf_lut rbatt_sf = {
|
||||
}
|
||||
};
|
||||
|
||||
struct pm8921_bms_battery_data palladium_1500_data = {
|
||||
struct bms_battery_data palladium_1500_data = {
|
||||
.fcc = 1500,
|
||||
.fcc_temp_lut = &fcc_temp,
|
||||
.pc_temp_ocv_lut = &pc_temp_ocv,
|
||||
|
||||
@@ -382,16 +382,17 @@ static int apq8064_pm8921_therm_mitigation[] = {
|
||||
#define CHG_TERM_MA 100
|
||||
static struct pm8921_charger_platform_data
|
||||
apq8064_pm8921_chg_pdata __devinitdata = {
|
||||
.safety_time = 180,
|
||||
.update_time = 60000,
|
||||
.max_voltage = MAX_VOLTAGE_MV,
|
||||
.min_voltage = 3200,
|
||||
.uvd_thresh_voltage = 4050,
|
||||
.alarm_voltage = 3400,
|
||||
.resume_voltage_delta = 100,
|
||||
.alarm_low_mv = 3400,
|
||||
.alarm_high_mv = 4000,
|
||||
.resume_voltage_delta = 60,
|
||||
.resume_charge_percent = 99,
|
||||
.term_current = CHG_TERM_MA,
|
||||
.cool_temp = 10,
|
||||
.warm_temp = 40,
|
||||
.warm_temp = 45,
|
||||
.temp_check_period = 1,
|
||||
.max_bat_chg_current = 1100,
|
||||
.cool_bat_chg_current = 350,
|
||||
@@ -404,20 +405,22 @@ apq8064_pm8921_chg_pdata __devinitdata = {
|
||||
|
||||
static struct pm8xxx_ccadc_platform_data
|
||||
apq8064_pm8xxx_ccadc_pdata = {
|
||||
.r_sense = 10,
|
||||
.r_sense_uohm = 10000,
|
||||
.calib_delay_ms = 600000,
|
||||
};
|
||||
|
||||
static struct pm8921_bms_platform_data
|
||||
apq8064_pm8921_bms_pdata __devinitdata = {
|
||||
.battery_type = BATT_UNKNOWN,
|
||||
.r_sense = 10,
|
||||
.r_sense_uohm = 10000,
|
||||
.v_cutoff = 3400,
|
||||
.max_voltage_uv = MAX_VOLTAGE_MV * 1000,
|
||||
.rconn_mohm = 18,
|
||||
.shutdown_soc_valid_limit = 20,
|
||||
.adjust_soc_low_threshold = 25,
|
||||
.chg_term_ua = CHG_TERM_MA * 1000,
|
||||
.normal_voltage_calc_ms = 20000,
|
||||
.low_voltage_calc_ms = 1000,
|
||||
};
|
||||
|
||||
static struct pm8921_platform_data
|
||||
@@ -497,4 +500,7 @@ void __init apq8064_init_pmic(void)
|
||||
} else if (machine_is_apq8064_cdp()) {
|
||||
apq8064_pm8921_chg_pdata.has_dc_supply = true;
|
||||
}
|
||||
|
||||
if (!machine_is_apq8064_mtp() && !machine_is_apq8064_liquid())
|
||||
apq8064_pm8921_chg_pdata.battery_less_hardware = 1;
|
||||
}
|
||||
|
||||
@@ -90,6 +90,7 @@ VREG_CONSUMERS(L13) = {
|
||||
};
|
||||
VREG_CONSUMERS(L14) = {
|
||||
REGULATOR_SUPPLY("8921_l14", NULL),
|
||||
REGULATOR_SUPPLY("vreg_xoadc", "pm8921-charger"),
|
||||
};
|
||||
VREG_CONSUMERS(L15) = {
|
||||
REGULATOR_SUPPLY("8921_l15", NULL),
|
||||
|
||||
@@ -313,16 +313,17 @@ static int pm8921_therm_mitigation[] = {
|
||||
#define MAX_VOLTAGE_MV 4200
|
||||
#define CHG_TERM_MA 100
|
||||
static struct pm8921_charger_platform_data pm8921_chg_pdata __devinitdata = {
|
||||
.safety_time = 180,
|
||||
.update_time = 60000,
|
||||
.max_voltage = MAX_VOLTAGE_MV,
|
||||
.min_voltage = 3200,
|
||||
.uvd_thresh_voltage = 4050,
|
||||
.alarm_voltage = 3400,
|
||||
.resume_voltage_delta = 100,
|
||||
.alarm_low_mv = 3400,
|
||||
.alarm_high_mv = 4000,
|
||||
.resume_voltage_delta = 60,
|
||||
.resume_charge_percent = 99,
|
||||
.term_current = CHG_TERM_MA,
|
||||
.cool_temp = 10,
|
||||
.warm_temp = 40,
|
||||
.warm_temp = 45,
|
||||
.temp_check_period = 1,
|
||||
.max_bat_chg_current = 1100,
|
||||
.cool_bat_chg_current = 350,
|
||||
@@ -434,7 +435,7 @@ static struct pm8xxx_led_platform_data pm8xxx_leds_pdata = {
|
||||
};
|
||||
|
||||
static struct pm8xxx_ccadc_platform_data pm8xxx_ccadc_pdata = {
|
||||
.r_sense = 10,
|
||||
.r_sense_uohm = 10000,
|
||||
.calib_delay_ms = 600000,
|
||||
};
|
||||
|
||||
@@ -462,13 +463,15 @@ static struct pm8xxx_spk_platform_data pm8xxx_spk_pdata = {
|
||||
|
||||
static struct pm8921_bms_platform_data pm8921_bms_pdata __devinitdata = {
|
||||
.battery_type = BATT_UNKNOWN,
|
||||
.r_sense = 10,
|
||||
.r_sense_uohm = 10000,
|
||||
.v_cutoff = 3400,
|
||||
.max_voltage_uv = MAX_VOLTAGE_MV * 1000,
|
||||
.shutdown_soc_valid_limit = 20,
|
||||
.adjust_soc_low_threshold = 25,
|
||||
.chg_term_ua = CHG_TERM_MA * 1000,
|
||||
.rconn_mohm = 18,
|
||||
.normal_voltage_calc_ms = 20000,
|
||||
.low_voltage_calc_ms = 1000,
|
||||
};
|
||||
|
||||
static struct pm8038_platform_data pm8038_platform_data __devinitdata = {
|
||||
@@ -590,4 +593,7 @@ void __init msm8930_init_pmic(void)
|
||||
else if (machine_is_msm8930_cdp())
|
||||
pm8921_chg_pdata.has_dc_supply = true;
|
||||
}
|
||||
|
||||
if (!machine_is_msm8930_mtp())
|
||||
pm8921_chg_pdata.battery_less_hardware = 1;
|
||||
}
|
||||
|
||||
@@ -396,16 +396,17 @@ static int pm8921_therm_mitigation[] = {
|
||||
#define MAX_VOLTAGE_MV 4200
|
||||
#define CHG_TERM_MA 100
|
||||
static struct pm8921_charger_platform_data pm8921_chg_pdata __devinitdata = {
|
||||
.safety_time = 180,
|
||||
.update_time = 60000,
|
||||
.max_voltage = MAX_VOLTAGE_MV,
|
||||
.min_voltage = 3200,
|
||||
.uvd_thresh_voltage = 4050,
|
||||
.alarm_voltage = 3400,
|
||||
.resume_voltage_delta = 100,
|
||||
.alarm_low_mv = 3400,
|
||||
.alarm_high_mv = 4000,
|
||||
.resume_voltage_delta = 60,
|
||||
.resume_charge_percent = 99,
|
||||
.term_current = CHG_TERM_MA,
|
||||
.cool_temp = 10,
|
||||
.warm_temp = 40,
|
||||
.warm_temp = 45,
|
||||
.temp_check_period = 1,
|
||||
.max_bat_chg_current = 1100,
|
||||
.cool_bat_chg_current = 350,
|
||||
@@ -423,13 +424,15 @@ static struct pm8xxx_misc_platform_data pm8xxx_misc_pdata = {
|
||||
|
||||
static struct pm8921_bms_platform_data pm8921_bms_pdata __devinitdata = {
|
||||
.battery_type = BATT_UNKNOWN,
|
||||
.r_sense = 10,
|
||||
.r_sense_uohm = 10000,
|
||||
.v_cutoff = 3400,
|
||||
.max_voltage_uv = MAX_VOLTAGE_MV * 1000,
|
||||
.rconn_mohm = 18,
|
||||
.shutdown_soc_valid_limit = 20,
|
||||
.adjust_soc_low_threshold = 25,
|
||||
.chg_term_ua = CHG_TERM_MA * 1000,
|
||||
.normal_voltage_calc_ms = 20000,
|
||||
.low_voltage_calc_ms = 1000,
|
||||
};
|
||||
|
||||
#define PM8921_LC_LED_MAX_CURRENT 4 /* I = 4mA */
|
||||
@@ -551,7 +554,7 @@ static struct pm8xxx_led_platform_data pm8xxx_leds_pdata = {
|
||||
};
|
||||
|
||||
static struct pm8xxx_ccadc_platform_data pm8xxx_ccadc_pdata = {
|
||||
.r_sense = 10,
|
||||
.r_sense_uohm = 10000,
|
||||
.calib_delay_ms = 600000,
|
||||
};
|
||||
|
||||
@@ -610,4 +613,8 @@ void __init msm8960_init_pmic(void)
|
||||
|
||||
if (machine_is_msm8960_fluid())
|
||||
pm8921_bms_pdata.rconn_mohm = 20;
|
||||
|
||||
if (!machine_is_msm8960_fluid() && !machine_is_msm8960_liquid()
|
||||
&& !machine_is_msm8960_mtp())
|
||||
pm8921_chg_pdata.battery_less_hardware = 1;
|
||||
}
|
||||
|
||||
@@ -89,6 +89,7 @@ VREG_CONSUMERS(L12) = {
|
||||
VREG_CONSUMERS(L14) = {
|
||||
REGULATOR_SUPPLY("8921_l14", NULL),
|
||||
REGULATOR_SUPPLY("pa_therm", "pm8xxx-adc"),
|
||||
REGULATOR_SUPPLY("vreg_xoadc", "pm8921-charger"),
|
||||
};
|
||||
VREG_CONSUMERS(L15) = {
|
||||
REGULATOR_SUPPLY("8921_l15", NULL),
|
||||
|
||||
@@ -45,7 +45,6 @@
|
||||
#define PM8018_REVISION_MASK 0x000F
|
||||
|
||||
#define REG_PM8018_PON_CNTRL_3 0x01D
|
||||
#define PM8018_RESTART_REASON_MASK 0x07
|
||||
|
||||
#define SINGLE_IRQ_RESOURCE(_name, _irq) \
|
||||
{ \
|
||||
@@ -61,6 +60,7 @@ struct pm8018 {
|
||||
struct mfd_cell *mfd_regulators;
|
||||
struct pm8xxx_regulator_core_platform_data *regulator_cdata;
|
||||
u32 rev_registers;
|
||||
u8 restart_reason;
|
||||
};
|
||||
|
||||
static int pm8018_readb(const struct device *dev, u16 addr, u8 *val)
|
||||
@@ -125,6 +125,14 @@ static int pm8018_get_revision(const struct device *dev)
|
||||
return pmic->rev_registers & PM8018_REVISION_MASK;
|
||||
}
|
||||
|
||||
static u8 pm8018_restart_reason(const struct device *dev)
|
||||
{
|
||||
const struct pm8xxx_drvdata *pm8018_drvdata = dev_get_drvdata(dev);
|
||||
const struct pm8018 *pmic = pm8018_drvdata->pm_chip_data;
|
||||
|
||||
return pmic->restart_reason;
|
||||
}
|
||||
|
||||
static struct pm8xxx_drvdata pm8018_drvdata = {
|
||||
.pmic_readb = pm8018_readb,
|
||||
.pmic_writeb = pm8018_writeb,
|
||||
@@ -133,6 +141,7 @@ static struct pm8xxx_drvdata pm8018_drvdata = {
|
||||
.pmic_read_irq_stat = pm8018_read_irq_stat,
|
||||
.pmic_get_version = pm8018_get_version,
|
||||
.pmic_get_revision = pm8018_get_revision,
|
||||
.pmic_restart_reason = pm8018_restart_reason,
|
||||
};
|
||||
|
||||
static const struct resource gpio_cell_resources[] __devinitconst = {
|
||||
@@ -516,17 +525,6 @@ bail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const char * const pm8018_restart_reason[] = {
|
||||
[0] = "Unknown",
|
||||
[1] = "Triggered from CBL (external charger)",
|
||||
[2] = "Triggered from KPD (power key press)",
|
||||
[3] = "Triggered from CHG (usb charger insertion)",
|
||||
[4] = "Triggered from SMPL (sudden momentary power loss)",
|
||||
[5] = "Triggered from RTC (real time clock)",
|
||||
[6] = "Triggered by Hard Reset",
|
||||
[7] = "Triggered by General Purpose Trigger",
|
||||
};
|
||||
|
||||
static const char * const pm8018_rev_names[] = {
|
||||
[PM8XXX_REVISION_8018_TEST] = "test",
|
||||
[PM8XXX_REVISION_8018_1p0] = "1.0",
|
||||
@@ -594,8 +592,9 @@ static int __devinit pm8018_probe(struct platform_device *pdev)
|
||||
pr_err("Cannot read restart reason rc=%d\n", rc);
|
||||
goto err_read_rev;
|
||||
}
|
||||
val &= PM8018_RESTART_REASON_MASK;
|
||||
pr_info("PMIC Restart Reason: %s\n", pm8018_restart_reason[val]);
|
||||
val &= PM8XXX_RESTART_REASON_MASK;
|
||||
pr_info("PMIC Restart Reason: %s\n", pm8xxx_restart_reason_str[val]);
|
||||
pmic->restart_reason = val;
|
||||
|
||||
rc = pm8018_add_subdevices(pdata, pmic);
|
||||
if (rc) {
|
||||
|
||||
@@ -49,7 +49,6 @@
|
||||
#define PM8038_REVISION_MASK 0x000F
|
||||
|
||||
#define REG_PM8038_PON_CNTRL_3 0x01D
|
||||
#define PM8038_RESTART_REASON_MASK 0x07
|
||||
|
||||
#define SINGLE_IRQ_RESOURCE(_name, _irq) \
|
||||
{ \
|
||||
@@ -65,6 +64,7 @@ struct pm8038 {
|
||||
struct mfd_cell *mfd_regulators;
|
||||
struct pm8xxx_regulator_core_platform_data *regulator_cdata;
|
||||
u32 rev_registers;
|
||||
u8 restart_reason;
|
||||
};
|
||||
|
||||
static int pm8038_readb(const struct device *dev, u16 addr, u8 *val)
|
||||
@@ -129,6 +129,14 @@ static int pm8038_get_revision(const struct device *dev)
|
||||
return pmic->rev_registers & PM8038_REVISION_MASK;
|
||||
}
|
||||
|
||||
static u8 pm8038_restart_reason(const struct device *dev)
|
||||
{
|
||||
const struct pm8xxx_drvdata *pm8038_drvdata = dev_get_drvdata(dev);
|
||||
const struct pm8038 *pmic = pm8038_drvdata->pm_chip_data;
|
||||
|
||||
return pmic->restart_reason;
|
||||
}
|
||||
|
||||
static struct pm8xxx_drvdata pm8038_drvdata = {
|
||||
.pmic_readb = pm8038_readb,
|
||||
.pmic_writeb = pm8038_writeb,
|
||||
@@ -137,6 +145,7 @@ static struct pm8xxx_drvdata pm8038_drvdata = {
|
||||
.pmic_read_irq_stat = pm8038_read_irq_stat,
|
||||
.pmic_get_version = pm8038_get_version,
|
||||
.pmic_get_revision = pm8038_get_revision,
|
||||
.pmic_restart_reason = pm8038_restart_reason,
|
||||
};
|
||||
|
||||
static const struct resource gpio_cell_resources[] __devinitconst = {
|
||||
@@ -702,6 +711,8 @@ pm8038_add_subdevices(const struct pm8038_platform_data *pdata,
|
||||
}
|
||||
|
||||
if (pdata->ccadc_pdata) {
|
||||
pdata->ccadc_pdata->ccadc_cdata.batt_temp_channel
|
||||
= CHANNEL_BATT_THERM;
|
||||
ccadc_cell.platform_data = pdata->ccadc_pdata;
|
||||
ccadc_cell.pdata_size =
|
||||
sizeof(struct pm8xxx_ccadc_platform_data);
|
||||
@@ -723,17 +734,6 @@ bail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const char * const pm8038_restart_reason[] = {
|
||||
[0] = "Unknown",
|
||||
[1] = "Triggered from CBL (external charger)",
|
||||
[2] = "Triggered from KPD (power key press)",
|
||||
[3] = "Triggered from CHG (usb charger insertion)",
|
||||
[4] = "Triggered from SMPL (sudden momentary power loss)",
|
||||
[5] = "Triggered from RTC (real time clock)",
|
||||
[6] = "Triggered by Hard Reset",
|
||||
[7] = "Triggered by General Purpose Trigger",
|
||||
};
|
||||
|
||||
static const char * const pm8038_rev_names[] = {
|
||||
[PM8XXX_REVISION_8038_TEST] = "test",
|
||||
[PM8XXX_REVISION_8038_1p0] = "1.0",
|
||||
@@ -802,8 +802,9 @@ static int __devinit pm8038_probe(struct platform_device *pdev)
|
||||
pr_err("Cannot read restart reason rc=%d\n", rc);
|
||||
goto err_read_rev;
|
||||
}
|
||||
val &= PM8038_RESTART_REASON_MASK;
|
||||
pr_info("PMIC Restart Reason: %s\n", pm8038_restart_reason[val]);
|
||||
val &= PM8XXX_RESTART_REASON_MASK;
|
||||
pr_info("PMIC Restart Reason: %s\n", pm8xxx_restart_reason_str[val]);
|
||||
pmic->restart_reason = val;
|
||||
|
||||
rc = pm8038_add_subdevices(pdata, pmic);
|
||||
if (rc) {
|
||||
|
||||
@@ -63,6 +63,7 @@ struct pm8921 {
|
||||
struct mfd_cell *mfd_regulators;
|
||||
struct pm8xxx_regulator_core_platform_data *regulator_cdata;
|
||||
u32 rev_registers;
|
||||
u8 restart_reason;
|
||||
};
|
||||
|
||||
static int pm8921_readb(const struct device *dev, u16 addr, u8 *val)
|
||||
@@ -133,6 +134,14 @@ static int pm8921_get_revision(const struct device *dev)
|
||||
return pmic->rev_registers & PM8921_REVISION_MASK;
|
||||
}
|
||||
|
||||
static u8 pm8921_restart_reason(const struct device *dev)
|
||||
{
|
||||
const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev);
|
||||
const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data;
|
||||
|
||||
return pmic->restart_reason;
|
||||
}
|
||||
|
||||
static struct pm8xxx_drvdata pm8921_drvdata = {
|
||||
.pmic_readb = pm8921_readb,
|
||||
.pmic_writeb = pm8921_writeb,
|
||||
@@ -141,6 +150,7 @@ static struct pm8xxx_drvdata pm8921_drvdata = {
|
||||
.pmic_read_irq_stat = pm8921_read_irq_stat,
|
||||
.pmic_get_version = pm8921_get_version,
|
||||
.pmic_get_revision = pm8921_get_revision,
|
||||
.pmic_restart_reason = pm8921_restart_reason,
|
||||
};
|
||||
|
||||
static struct resource gpio_cell_resources[] = {
|
||||
@@ -794,6 +804,8 @@ pm8921_add_subdevices(const struct pm8921_platform_data *pdata,
|
||||
}
|
||||
|
||||
if (pdata->ccadc_pdata) {
|
||||
pdata->ccadc_pdata->ccadc_cdata.batt_temp_channel
|
||||
= CHANNEL_BATT_THERM;
|
||||
ccadc_cell.platform_data = pdata->ccadc_pdata;
|
||||
ccadc_cell.pdata_size =
|
||||
sizeof(struct pm8xxx_ccadc_platform_data);
|
||||
@@ -815,17 +827,6 @@ bail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const char * const pm8921_restart_reason[] = {
|
||||
[0] = "Unknown",
|
||||
[1] = "Triggered from CBL (external charger)",
|
||||
[2] = "Triggered from KPD (power key press)",
|
||||
[3] = "Triggered from CHG (usb charger insertion)",
|
||||
[4] = "Triggered from SMPL (sudden momentary power loss)",
|
||||
[5] = "Triggered from RTC (real time clock)",
|
||||
[6] = "Triggered by Hard Reset",
|
||||
[7] = "Triggered by General Purpose Trigger",
|
||||
};
|
||||
|
||||
static const char * const pm8921_rev_names[] = {
|
||||
[PM8XXX_REVISION_8921_TEST] = "test",
|
||||
[PM8XXX_REVISION_8921_1p0] = "1.0",
|
||||
@@ -918,8 +919,9 @@ static int __devinit pm8921_probe(struct platform_device *pdev)
|
||||
pr_err("Cannot read restart reason rc=%d\n", rc);
|
||||
goto err_read_rev;
|
||||
}
|
||||
val &= PM8921_RESTART_REASON_MASK;
|
||||
pr_info("PMIC Restart Reason: %s\n", pm8921_restart_reason[val]);
|
||||
val &= PM8XXX_RESTART_REASON_MASK;
|
||||
pr_info("PMIC Restart Reason: %s\n", pm8xxx_restart_reason_str[val]);
|
||||
pmic->restart_reason = val;
|
||||
|
||||
rc = pm8921_add_subdevices(pdata, pmic);
|
||||
if (rc) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
|
||||
* Copyright (c) 2011-2012, Code Aurora Forum. 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
|
||||
@@ -206,9 +206,11 @@ static int pm_power_set_property(struct power_supply *psy,
|
||||
struct ltc4088_chg_chip *chip;
|
||||
|
||||
if (psy->type == POWER_SUPPLY_TYPE_USB) {
|
||||
chip = container_of(psy, struct ltc4088_chg_chip,
|
||||
usb_psy);
|
||||
chip = container_of(psy, struct ltc4088_chg_chip, usb_psy);
|
||||
switch (psp) {
|
||||
case POWER_SUPPLY_PROP_TYPE:
|
||||
psy.type = val->intval;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_ONLINE:
|
||||
ltc4088_set_charging(chip, val->intval);
|
||||
break;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
|
||||
/* Copyright (c) 2011-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
|
||||
@@ -17,12 +17,15 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/mfd/pm8xxx/core.h>
|
||||
#include <linux/mfd/pm8xxx/pm8xxx-adc.h>
|
||||
#include <linux/mfd/pm8xxx/ccadc.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/rtc.h>
|
||||
|
||||
#define CCADC_ANA_PARAM 0x240
|
||||
#define CCADC_DIG_PARAM 0x241
|
||||
@@ -67,13 +70,17 @@
|
||||
struct pm8xxx_ccadc_chip {
|
||||
struct device *dev;
|
||||
struct dentry *dent;
|
||||
unsigned int batt_temp_channel;
|
||||
u16 ccadc_offset;
|
||||
int ccadc_gain_uv;
|
||||
unsigned int revision;
|
||||
unsigned int calib_delay_ms;
|
||||
unsigned long last_calib_time;
|
||||
int last_calib_temp;
|
||||
int eoc_irq;
|
||||
int r_sense;
|
||||
int r_sense_uohm;
|
||||
struct delayed_work calib_ccadc_work;
|
||||
struct mutex calib_mutex;
|
||||
};
|
||||
|
||||
static struct pm8xxx_ccadc_chip *the_chip;
|
||||
@@ -312,6 +319,54 @@ static int calib_ccadc_program_trim(struct pm8xxx_ccadc_chip *chip,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_batt_temp(struct pm8xxx_ccadc_chip *chip, int *batt_temp)
|
||||
{
|
||||
int rc;
|
||||
struct pm8xxx_adc_chan_result result;
|
||||
|
||||
rc = pm8xxx_adc_read(chip->batt_temp_channel, &result);
|
||||
if (rc) {
|
||||
pr_err("error reading batt_temp_channel = %d, rc = %d\n",
|
||||
chip->batt_temp_channel, rc);
|
||||
return rc;
|
||||
}
|
||||
*batt_temp = result.physical;
|
||||
pr_debug("batt_temp phy = %lld meas = 0x%llx\n", result.physical,
|
||||
result.measurement);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_current_time(unsigned long *now_tm_sec)
|
||||
{
|
||||
struct rtc_time tm;
|
||||
struct rtc_device *rtc;
|
||||
int rc;
|
||||
|
||||
rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
|
||||
if (rtc == NULL) {
|
||||
pr_err("%s: unable to open rtc device (%s)\n",
|
||||
__FILE__, CONFIG_RTC_HCTOSYS_DEVICE);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = rtc_read_time(rtc, &tm);
|
||||
if (rc) {
|
||||
pr_err("Error reading rtc device (%s) : %d\n",
|
||||
CONFIG_RTC_HCTOSYS_DEVICE, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = rtc_valid_tm(&tm);
|
||||
if (rc) {
|
||||
pr_err("Invalid RTC time (%s): %d\n",
|
||||
CONFIG_RTC_HCTOSYS_DEVICE, rc);
|
||||
return rc;
|
||||
}
|
||||
rtc_tm_to_time(&tm, now_tm_sec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pm8xxx_calib_ccadc(void)
|
||||
{
|
||||
u8 data_msb, data_lsb, sec_cntrl;
|
||||
@@ -324,11 +379,12 @@ void pm8xxx_calib_ccadc(void)
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&the_chip->calib_mutex);
|
||||
rc = pm8xxx_readb(the_chip->dev->parent,
|
||||
ADC_ARB_SECP_CNTRL, &sec_cntrl);
|
||||
if (rc < 0) {
|
||||
pr_err("error = %d reading ADC_ARB_SECP_CNTRL\n", rc);
|
||||
return;
|
||||
goto calibration_unlock;
|
||||
}
|
||||
|
||||
rc = calib_ccadc_enable_arbiter(the_chip);
|
||||
@@ -460,6 +516,8 @@ void pm8xxx_calib_ccadc(void)
|
||||
pr_debug("error = %d programming gain trim\n", rc);
|
||||
bail:
|
||||
pm8xxx_writeb(the_chip->dev->parent, ADC_ARB_SECP_CNTRL, sec_cntrl);
|
||||
calibration_unlock:
|
||||
mutex_unlock(&the_chip->calib_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL(pm8xxx_calib_ccadc);
|
||||
|
||||
@@ -480,6 +538,9 @@ static irqreturn_t pm8921_bms_ccadc_eoc_handler(int irq, void *data)
|
||||
struct pm8xxx_ccadc_chip *chip = data;
|
||||
int rc;
|
||||
|
||||
if (!the_chip)
|
||||
goto out;
|
||||
|
||||
pr_debug("irq = %d triggered\n", irq);
|
||||
data_msb = chip->ccadc_offset >> 8;
|
||||
data_lsb = chip->ccadc_offset;
|
||||
@@ -488,6 +549,7 @@ static irqreturn_t pm8921_bms_ccadc_eoc_handler(int irq, void *data)
|
||||
data_msb, data_lsb, 0);
|
||||
disable_irq_nosync(chip->eoc_irq);
|
||||
|
||||
out:
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -558,7 +620,8 @@ int pm8xxx_ccadc_get_battery_current(int *bat_current_ua)
|
||||
return rc;
|
||||
}
|
||||
|
||||
*bat_current_ua = voltage_uv * 1000/the_chip->r_sense;
|
||||
*bat_current_ua = div_s64((s64)voltage_uv * 1000000LL,
|
||||
the_chip->r_sense_uohm);
|
||||
/*
|
||||
* ccadc reads +ve current when the battery is charging
|
||||
* We need to return -ve if the battery is charging
|
||||
@@ -671,12 +734,15 @@ static int __devinit pm8xxx_ccadc_probe(struct platform_device *pdev)
|
||||
chip->dev = &pdev->dev;
|
||||
chip->revision = pm8xxx_get_revision(chip->dev->parent);
|
||||
chip->eoc_irq = res->start;
|
||||
chip->r_sense = pdata->r_sense;
|
||||
chip->r_sense_uohm = pdata->r_sense_uohm;
|
||||
chip->calib_delay_ms = pdata->calib_delay_ms;
|
||||
chip->batt_temp_channel = pdata->ccadc_cdata.batt_temp_channel;
|
||||
mutex_init(&chip->calib_mutex);
|
||||
|
||||
calib_ccadc_read_offset_and_gain(chip,
|
||||
&chip->ccadc_gain_uv,
|
||||
&chip->ccadc_offset);
|
||||
irq_set_status_flags(chip->eoc_irq, IRQ_NOAUTOEN);
|
||||
rc = request_irq(chip->eoc_irq,
|
||||
pm8921_bms_ccadc_eoc_handler, IRQF_TRIGGER_RISING,
|
||||
"bms_eoc_ccadc", chip);
|
||||
@@ -685,9 +751,6 @@ static int __devinit pm8xxx_ccadc_probe(struct platform_device *pdev)
|
||||
goto free_chip;
|
||||
}
|
||||
|
||||
|
||||
disable_irq_nosync(chip->eoc_irq);
|
||||
|
||||
platform_set_drvdata(pdev, chip);
|
||||
the_chip = chip;
|
||||
INIT_DELAYED_WORK(&chip->calib_ccadc_work, calibrate_ccadc_work);
|
||||
@@ -698,6 +761,7 @@ static int __devinit pm8xxx_ccadc_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
|
||||
free_chip:
|
||||
mutex_destroy(&chip->calib_mutex);
|
||||
kfree(chip);
|
||||
return rc;
|
||||
}
|
||||
@@ -712,12 +776,50 @@ static int __devexit pm8xxx_ccadc_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CCADC_CALIB_TEMP_THRESH 20
|
||||
static int pm8xxx_ccadc_resume(struct device *dev)
|
||||
{
|
||||
int rc, batt_temp, delta_temp;
|
||||
unsigned long current_time_sec;
|
||||
unsigned long time_since_last_calib;
|
||||
|
||||
rc = get_batt_temp(the_chip, &batt_temp);
|
||||
if (rc) {
|
||||
pr_err("unable to get batt_temp: %d\n", rc);
|
||||
return 0;
|
||||
}
|
||||
rc = get_current_time(¤t_time_sec);
|
||||
if (rc) {
|
||||
pr_err("unable to get current time: %d\n", rc);
|
||||
return 0;
|
||||
}
|
||||
if (current_time_sec > the_chip->last_calib_time) {
|
||||
time_since_last_calib = current_time_sec -
|
||||
the_chip->last_calib_time;
|
||||
delta_temp = abs(batt_temp - the_chip->last_calib_temp);
|
||||
pr_debug("time since last calib: %lu, delta_temp = %d\n",
|
||||
time_since_last_calib, delta_temp);
|
||||
if (time_since_last_calib >= the_chip->calib_delay_ms/1000
|
||||
|| delta_temp > CCADC_CALIB_TEMP_THRESH) {
|
||||
the_chip->last_calib_time = current_time_sec;
|
||||
the_chip->last_calib_temp = batt_temp;
|
||||
pm8xxx_calib_ccadc();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops pm8xxx_ccadc_pm_ops = {
|
||||
.resume = pm8xxx_ccadc_resume,
|
||||
};
|
||||
|
||||
static struct platform_driver pm8xxx_ccadc_driver = {
|
||||
.probe = pm8xxx_ccadc_probe,
|
||||
.remove = __devexit_p(pm8xxx_ccadc_remove),
|
||||
.driver = {
|
||||
.name = PM8XXX_CCADC_DEV_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
.pm = &pm8xxx_ccadc_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -1079,7 +1079,7 @@ static int msm_otg_notify_chg_type(struct msm_otg *motg)
|
||||
motg->chg_type == USB_ACA_C_CHARGER))
|
||||
charger_type = POWER_SUPPLY_TYPE_USB_ACA;
|
||||
else
|
||||
charger_type = POWER_SUPPLY_TYPE_BATTERY;
|
||||
charger_type = POWER_SUPPLY_TYPE_UNKNOWN;
|
||||
|
||||
return pm8921_set_usb_power_supply_type(charger_type);
|
||||
}
|
||||
|
||||
155
include/linux/mfd/pm8xxx/batterydata-lib.h
Normal file
155
include/linux/mfd/pm8xxx/batterydata-lib.h
Normal file
@@ -0,0 +1,155 @@
|
||||
/* Copyright (c) 2012, 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.
|
||||
*/
|
||||
|
||||
#ifndef __PM8XXX_BMS_BATTERYDATA_H
|
||||
#define __PM8XXX_BMS_BATTERYDATA_H
|
||||
|
||||
#include <linux/errno.h>
|
||||
|
||||
#define FCC_CC_COLS 5
|
||||
#define FCC_TEMP_COLS 8
|
||||
|
||||
#define PC_CC_ROWS 29
|
||||
#define PC_CC_COLS 13
|
||||
|
||||
#define PC_TEMP_ROWS 29
|
||||
#define PC_TEMP_COLS 8
|
||||
|
||||
#define MAX_SINGLE_LUT_COLS 20
|
||||
|
||||
struct single_row_lut {
|
||||
int x[MAX_SINGLE_LUT_COLS];
|
||||
int y[MAX_SINGLE_LUT_COLS];
|
||||
int cols;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sf_lut -
|
||||
* @rows: number of percent charge entries should be <= PC_CC_ROWS
|
||||
* @cols: number of charge cycle entries should be <= PC_CC_COLS
|
||||
* @row_entries: the charge cycles/temperature at which sf data
|
||||
* is available in the table.
|
||||
* The charge cycles must be in increasing order from 0 to rows.
|
||||
* @percent: the percent charge at which sf data is available in the table
|
||||
* The percentcharge must be in decreasing order from 0 to cols.
|
||||
* @sf: the scaling factor data
|
||||
*/
|
||||
struct sf_lut {
|
||||
int rows;
|
||||
int cols;
|
||||
int row_entries[PC_CC_COLS];
|
||||
int percent[PC_CC_ROWS];
|
||||
int sf[PC_CC_ROWS][PC_CC_COLS];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pc_temp_ocv_lut -
|
||||
* @rows: number of percent charge entries should be <= PC_TEMP_ROWS
|
||||
* @cols: number of temperature entries should be <= PC_TEMP_COLS
|
||||
* @temp: the temperatures at which ocv data is available in the table
|
||||
* The temperatures must be in increasing order from 0 to rows.
|
||||
* @percent: the percent charge at which ocv data is available in the table
|
||||
* The percentcharge must be in decreasing order from 0 to cols.
|
||||
* @ocv: the open circuit voltage
|
||||
*/
|
||||
struct pc_temp_ocv_lut {
|
||||
int rows;
|
||||
int cols;
|
||||
int temp[PC_TEMP_COLS];
|
||||
int percent[PC_TEMP_ROWS];
|
||||
int ocv[PC_TEMP_ROWS][PC_TEMP_COLS];
|
||||
};
|
||||
|
||||
enum battery_type {
|
||||
BATT_UNKNOWN = 0,
|
||||
BATT_PALLADIUM,
|
||||
BATT_DESAY,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct bms_battery_data -
|
||||
* @fcc: full charge capacity (mAmpHour)
|
||||
* @fcc_temp_lut: table to get fcc at a given temp
|
||||
* @pc_temp_ocv_lut: table to get percent charge given batt temp and cycles
|
||||
* @pc_sf_lut: table to get percent charge scaling factor given cycles
|
||||
* and percent charge
|
||||
* @rbatt_sf_lut: table to get battery resistance scaling factor given
|
||||
* temperature and percent charge
|
||||
* @default_rbatt_mohm: the default value of battery resistance to use when
|
||||
* readings from bms are not available.
|
||||
* @delta_rbatt_mohm: the resistance to be added towards lower soc to
|
||||
* compensate for battery capacitance.
|
||||
*/
|
||||
|
||||
struct bms_battery_data {
|
||||
unsigned int fcc;
|
||||
struct single_row_lut *fcc_temp_lut;
|
||||
struct single_row_lut *fcc_sf_lut;
|
||||
struct pc_temp_ocv_lut *pc_temp_ocv_lut;
|
||||
struct sf_lut *pc_sf_lut;
|
||||
struct sf_lut *rbatt_sf_lut;
|
||||
int default_rbatt_mohm;
|
||||
int delta_rbatt_mohm;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_PM8921_BMS) || \
|
||||
defined(CONFIG_PM8921_BMS_MODULE)
|
||||
extern struct bms_battery_data palladium_1500_data;
|
||||
extern struct bms_battery_data desay_5200_data;
|
||||
|
||||
int interpolate_fcc(struct single_row_lut *fcc_temp_lut, int batt_temp);
|
||||
int interpolate_scalingfactor(struct sf_lut *sf_lut, int row_entry, int pc);
|
||||
int interpolate_scalingfactor_fcc(struct single_row_lut *fcc_sf_lut,
|
||||
int cycles);
|
||||
int interpolate_pc(struct pc_temp_ocv_lut *pc_temp_ocv,
|
||||
int batt_temp_degc, int ocv);
|
||||
int interpolate_ocv(struct pc_temp_ocv_lut *pc_temp_ocv,
|
||||
int batt_temp_degc, int pc);
|
||||
int linear_interpolate(int y0, int x0, int y1, int x1, int x);
|
||||
int is_between(int left, int right, int value);
|
||||
#else
|
||||
static inline int interpolate_fcc(struct single_row_lut *fcc_temp_lut,
|
||||
int batt_temp)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
static inline int interpolate_scalingfactor(struct sf_lut *sf_lut,
|
||||
int row_entry, int pc)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
static inline int interpolate_scalingfactor_fcc(
|
||||
struct single_row_lut *fcc_sf_lut, int cycles)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
static inline int interpolate_pc(struct pc_temp_ocv_lut *pc_temp_ocv,
|
||||
int batt_temp_degc, int ocv)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
static inline int interpolate_ocv(struct pc_temp_ocv_lut *pc_temp_ocv,
|
||||
int batt_temp_degc, int pc)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
static inline int linear_interpolate(int y0, int x0, int y1, int x1, int x)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
static inline int is_between(int left, int right, int value)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -17,14 +17,20 @@
|
||||
|
||||
#define PM8XXX_CCADC_DEV_NAME "pm8xxx-ccadc"
|
||||
|
||||
struct pm8xxx_ccadc_core_data {
|
||||
unsigned int batt_temp_channel;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pm8xxx_ccadc_platform_data -
|
||||
* @r_sense: sense resistor value in (mOhms)
|
||||
* @ccadc_cdata: core data for the ccadc driver containing channel info
|
||||
* @r_sense_uohm: sense resistor value in (micro Ohms)
|
||||
* @calib_delay_ms: how often should the adc calculate gain and offset
|
||||
*/
|
||||
struct pm8xxx_ccadc_platform_data {
|
||||
int r_sense;
|
||||
unsigned int calib_delay_ms;
|
||||
struct pm8xxx_ccadc_core_data ccadc_cdata;
|
||||
int r_sense_uohm;
|
||||
unsigned int calib_delay_ms;
|
||||
};
|
||||
|
||||
#define CCADC_READING_RESOLUTION_N 542535
|
||||
|
||||
@@ -75,6 +75,27 @@ enum pm8xxx_version {
|
||||
#define PM8XXX_REVISION_8917_TEST 0
|
||||
#define PM8XXX_REVISION_8917_1p0 1
|
||||
|
||||
#define PM8XXX_RESTART_UNKNOWN 0
|
||||
#define PM8XXX_RESTART_CBL 1
|
||||
#define PM8XXX_RESTART_KPD 2
|
||||
#define PM8XXX_RESTART_CHG 3
|
||||
#define PM8XXX_RESTART_SMPL 4
|
||||
#define PM8XXX_RESTART_RTC 5
|
||||
#define PM8XXX_RESTART_HARD_RESET 6
|
||||
#define PM8XXX_RESTART_GEN_PURPOSE 7
|
||||
#define PM8XXX_RESTART_REASON_MASK 0x07
|
||||
|
||||
static const char * const pm8xxx_restart_reason_str[] = {
|
||||
[0] = "Unknown",
|
||||
[1] = "Triggered from CBL (external charger)",
|
||||
[2] = "Triggered from KPD (power key press)",
|
||||
[3] = "Triggered from CHG (usb charger insertion)",
|
||||
[4] = "Triggered from SMPL (sudden momentary power loss)",
|
||||
[5] = "Triggered from RTC (real time clock)",
|
||||
[6] = "Triggered by Hard Reset",
|
||||
[7] = "Triggered by General Purpose Trigger",
|
||||
};
|
||||
|
||||
struct pm8xxx_drvdata {
|
||||
int (*pmic_readb) (const struct device *dev,
|
||||
u16 addr, u8 *val);
|
||||
@@ -88,6 +109,8 @@ struct pm8xxx_drvdata {
|
||||
int irq);
|
||||
enum pm8xxx_version (*pmic_get_version) (const struct device *dev);
|
||||
int (*pmic_get_revision) (const struct device *dev);
|
||||
u8 (*pmic_restart_reason)
|
||||
(const struct device *dev);
|
||||
void *pm_chip_data;
|
||||
};
|
||||
|
||||
@@ -156,4 +179,12 @@ static inline int pm8xxx_get_revision(const struct device *dev)
|
||||
return dd->pmic_get_revision(dev);
|
||||
}
|
||||
|
||||
static inline u8 pm8xxx_restart_reason(const struct device *dev)
|
||||
{
|
||||
struct pm8xxx_drvdata *dd = dev_get_drvdata(dev);
|
||||
|
||||
if (!dd)
|
||||
return -EINVAL;
|
||||
return dd->pmic_restart_reason(dev);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
|
||||
/* Copyright (c) 2011-2013, Code Aurora Forum. 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
|
||||
@@ -14,87 +14,10 @@
|
||||
#define __PM8XXX_BMS_H
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/mfd/pm8xxx/batterydata-lib.h>
|
||||
|
||||
#define PM8921_BMS_DEV_NAME "pm8921-bms"
|
||||
|
||||
#define FCC_CC_COLS 5
|
||||
#define FCC_TEMP_COLS 8
|
||||
|
||||
#define PC_CC_ROWS 29
|
||||
#define PC_CC_COLS 13
|
||||
|
||||
#define PC_TEMP_ROWS 29
|
||||
#define PC_TEMP_COLS 8
|
||||
|
||||
#define MAX_SINGLE_LUT_COLS 20
|
||||
|
||||
struct single_row_lut {
|
||||
int x[MAX_SINGLE_LUT_COLS];
|
||||
int y[MAX_SINGLE_LUT_COLS];
|
||||
int cols;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sf_lut -
|
||||
* @rows: number of percent charge entries should be <= PC_CC_ROWS
|
||||
* @cols: number of charge cycle entries should be <= PC_CC_COLS
|
||||
* @row_entries: the charge cycles/temperature at which sf data
|
||||
* is available in the table.
|
||||
* The charge cycles must be in increasing order from 0 to rows.
|
||||
* @percent: the percent charge at which sf data is available in the table
|
||||
* The percentcharge must be in decreasing order from 0 to cols.
|
||||
* @sf: the scaling factor data
|
||||
*/
|
||||
struct sf_lut {
|
||||
int rows;
|
||||
int cols;
|
||||
int row_entries[PC_CC_COLS];
|
||||
int percent[PC_CC_ROWS];
|
||||
int sf[PC_CC_ROWS][PC_CC_COLS];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pc_temp_ocv_lut -
|
||||
* @rows: number of percent charge entries should be <= PC_TEMP_ROWS
|
||||
* @cols: number of temperature entries should be <= PC_TEMP_COLS
|
||||
* @temp: the temperatures at which ocv data is available in the table
|
||||
* The temperatures must be in increasing order from 0 to rows.
|
||||
* @percent: the percent charge at which ocv data is available in the table
|
||||
* The percentcharge must be in decreasing order from 0 to cols.
|
||||
* @ocv: the open circuit voltage
|
||||
*/
|
||||
struct pc_temp_ocv_lut {
|
||||
int rows;
|
||||
int cols;
|
||||
int temp[PC_TEMP_COLS];
|
||||
int percent[PC_TEMP_ROWS];
|
||||
int ocv[PC_TEMP_ROWS][PC_TEMP_COLS];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pm8921_bms_battery_data -
|
||||
* @fcc: full charge capacity (mAmpHour)
|
||||
* @fcc_temp_lut: table to get fcc at a given temp
|
||||
* @pc_temp_ocv_lut: table to get percent charge given batt temp and cycles
|
||||
* @pc_sf_lut: table to get percent charge scaling factor given cycles
|
||||
* and percent charge
|
||||
* @rbatt_sf_lut: table to get battery resistance scaling factor given
|
||||
* temperature and percent charge
|
||||
* @default_rbatt_mohm: the default value of battery resistance to use when
|
||||
* readings from bms are not available.
|
||||
* @delta_rbatt_mohm: the resistance to be added towards lower soc to
|
||||
* compensate for battery capacitance.
|
||||
*/
|
||||
struct pm8921_bms_battery_data {
|
||||
unsigned int fcc;
|
||||
struct single_row_lut *fcc_temp_lut;
|
||||
struct single_row_lut *fcc_sf_lut;
|
||||
struct pc_temp_ocv_lut *pc_temp_ocv_lut;
|
||||
struct sf_lut *pc_sf_lut;
|
||||
struct sf_lut *rbatt_sf_lut;
|
||||
int default_rbatt_mohm;
|
||||
int delta_rbatt_mohm;
|
||||
};
|
||||
|
||||
struct pm8xxx_bms_core_data {
|
||||
unsigned int batt_temp_channel;
|
||||
@@ -104,27 +27,25 @@ struct pm8xxx_bms_core_data {
|
||||
unsigned int batt_id_channel;
|
||||
};
|
||||
|
||||
enum battery_type {
|
||||
BATT_UNKNOWN = 0,
|
||||
BATT_PALLADIUM,
|
||||
BATT_DESAY,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pm8921_bms_platform_data -
|
||||
* @batt_type: allows to force chose battery calibration data
|
||||
* @r_sense: sense resistor value in (mOhms)
|
||||
* @r_sense_uohm: sense resistor value in (micro Ohms)
|
||||
* @i_test: current at which the unusable charger cutoff is to be
|
||||
* calculated or the peak system current (mA)
|
||||
* @v_cutoff: the loaded voltage at which the battery
|
||||
* is considered empty(mV)
|
||||
* @enable_fcc_learning: if set the driver will learn full charge
|
||||
* capacity of the battery upon end of charge
|
||||
* @normal_voltage_calc_ms: The period of soc calculation in ms when battery
|
||||
* voltage higher than cutoff voltage
|
||||
* @low_voltage_calc_ms: The period of soc calculation in ms when battery
|
||||
* voltage is near cutoff voltage
|
||||
*/
|
||||
struct pm8921_bms_platform_data {
|
||||
struct pm8xxx_bms_core_data bms_cdata;
|
||||
enum battery_type battery_type;
|
||||
unsigned int r_sense;
|
||||
int r_sense_uohm;
|
||||
unsigned int i_test;
|
||||
unsigned int v_cutoff;
|
||||
unsigned int max_voltage_uv;
|
||||
@@ -134,11 +55,11 @@ struct pm8921_bms_platform_data {
|
||||
int ignore_shutdown_soc;
|
||||
int adjust_soc_low_threshold;
|
||||
int chg_term_ua;
|
||||
int normal_voltage_calc_ms;
|
||||
int low_voltage_calc_ms;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_PM8921_BMS) || defined(CONFIG_PM8921_BMS_MODULE)
|
||||
extern struct pm8921_bms_battery_data palladium_1500_data;
|
||||
extern struct pm8921_bms_battery_data desay_5200_data;
|
||||
/**
|
||||
* pm8921_bms_get_vsense_avg - return the voltage across the sense
|
||||
* resitor in microvolts
|
||||
@@ -202,9 +123,11 @@ void pm8921_bms_calibrate_hkadc(void);
|
||||
int pm8921_bms_get_simultaneous_battery_voltage_and_current(int *ibat_ua,
|
||||
int *vbat_uv);
|
||||
/**
|
||||
* pm8921_bms_get_rbatt - function to get the battery resistance in mOhm.
|
||||
* pm8921_bms_get_current_max
|
||||
* - function to get the max current that can be drawn from
|
||||
* the battery before it dips below the min allowed voltage
|
||||
*/
|
||||
int pm8921_bms_get_rbatt(void);
|
||||
int pm8921_bms_get_current_max(void);
|
||||
/**
|
||||
* pm8921_bms_invalidate_shutdown_soc - function to notify the bms driver that
|
||||
* the battery was replaced between reboot
|
||||
@@ -212,6 +135,15 @@ int pm8921_bms_get_rbatt(void);
|
||||
* soc stored in a coincell backed register
|
||||
*/
|
||||
void pm8921_bms_invalidate_shutdown_soc(void);
|
||||
|
||||
/**
|
||||
* pm8921_bms_cc_uah - function to get the coulomb counter based charge. Note
|
||||
* that the coulomb counter are reset when the current
|
||||
* consumption is low (below 8mA for more than 5 minutes),
|
||||
* This will lead in a very low coulomb counter charge
|
||||
* value upon wakeup from sleep.
|
||||
*/
|
||||
int pm8921_bms_cc_uah(int *cc_uah);
|
||||
#else
|
||||
static inline int pm8921_bms_get_vsense_avg(int *result)
|
||||
{
|
||||
@@ -250,6 +182,14 @@ static inline int pm8921_bms_get_rbatt(void)
|
||||
static inline void pm8921_bms_invalidate_shutdown_soc(void)
|
||||
{
|
||||
}
|
||||
static inline int pm8921_bms_cc_uah(int *cc_uah)
|
||||
{
|
||||
return -ENXIO;
|
||||
}
|
||||
static inline int pm8921_bms_get_current_max(void)
|
||||
{
|
||||
return -ENXIO;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -58,19 +58,25 @@ enum pm8921_chg_led_src_config {
|
||||
|
||||
/**
|
||||
* struct pm8921_charger_platform_data -
|
||||
* @safety_time: max charging time in minutes incl. fast and trkl
|
||||
* valid range 4 to 512 min. PON default 120 min
|
||||
* @ttrkl_time: max trckl charging time in minutes
|
||||
* valid range 1 to 64 mins. PON default 15 min
|
||||
* @update_time: how often the userland be updated of the charging (msec)
|
||||
* @alarm_voltage: the voltage (mV) when lower battery alarm is triggered
|
||||
* @alarm_low_mv: the voltage (mV) when low battery alarm is triggered
|
||||
* @alarm_high_mv: the voltage (mV) when high battery alarm is triggered
|
||||
* @max_voltage: the max voltage (mV) the battery should be charged up to
|
||||
* @min_voltage: the voltage (mV) where charging method switches from
|
||||
* trickle to fast. This is also the minimum voltage the
|
||||
* system operates at
|
||||
* @uvd_thresh_voltage: the USB falling UVD threshold (mV) (PM8917 only)
|
||||
* @safe_current_ma: The upper limit of current allowed to be pushed in
|
||||
* battery. This ends up writing in a one time
|
||||
* programmable register.
|
||||
* @resume_voltage_delta: the (mV) drop to wait for before resume charging
|
||||
* after the battery has been fully charged
|
||||
* @resume_charge_percent: the % SOC the charger will drop to after the
|
||||
* battery is fully charged before resuming
|
||||
* charging.
|
||||
* @term_current: the charger current (mA) at which EOC happens
|
||||
* @cool_temp: the temperature (degC) at which the battery is
|
||||
* considered cool charging current and voltage is reduced.
|
||||
@@ -83,6 +89,7 @@ enum pm8921_chg_led_src_config {
|
||||
* area
|
||||
* @max_bat_chg_current: Max charge current of the battery in mA
|
||||
* Usually 70% of full charge capacity
|
||||
* @usb_max_current: Maximum USB current in mA
|
||||
* @cool_bat_chg_current: chg current (mA) when the battery is cool
|
||||
* @warm_bat_chg_current: chg current (mA) when the battery is warm
|
||||
* @cool_bat_voltage: chg voltage (mV) when the battery is cool
|
||||
@@ -90,10 +97,6 @@ enum pm8921_chg_led_src_config {
|
||||
* @get_batt_capacity_percent:
|
||||
* a board specific function to return battery
|
||||
* capacity. If null - a default one will be used
|
||||
* @dc_unplug_check: enables the reverse boosting fix for the DC_IN line
|
||||
* however, this should only be enabled for devices which
|
||||
* control the DC OVP FETs otherwise this option should
|
||||
* remain disabled
|
||||
* @has_dc_supply: report DC online if this bit is set in board file
|
||||
* @trkl_voltage: the trkl voltage in (mV) below which hw controlled
|
||||
* trkl charging happens with linear charger
|
||||
@@ -120,22 +123,44 @@ enum pm8921_chg_led_src_config {
|
||||
* resistance of the pads, connectors, battery terminals
|
||||
* and rsense.
|
||||
* @led_src_config: Power source for anode of charger indicator LED.
|
||||
* @btc_override: disable the comparators for conifugrations where a
|
||||
* suitable voltages don't appear on vbatt therm line
|
||||
* for the charger to detect battery is either cold / hot.
|
||||
* @btc_override_cold_degc: Temperature in degCelcius when the battery is
|
||||
* deemed cold and charging never happens. Used
|
||||
* only if btc_override = 1
|
||||
* @btc_override_hot_degc: Temperature in degCelcius when the battery is
|
||||
* deemed hot and charging never happens. Used
|
||||
* only if btc_override = 1
|
||||
* @btc_delay_ms: Delay in milliseconds to monitor the battery temperature
|
||||
* while charging when btc_override = 1
|
||||
* @btc_panic_if_cant_stop_chg: flag to instruct the driver to panic if the
|
||||
* driver couldn't stop charging when battery
|
||||
* temperature is out of bounds. Used only if
|
||||
* btc_override = 1
|
||||
* stop_chg_upon_expiry: flag to indicate that the charger driver should
|
||||
* stop charging the battery when the safety timer
|
||||
* expires. If not set the charger driver will
|
||||
* restart charging upon expiry.
|
||||
*/
|
||||
struct pm8921_charger_platform_data {
|
||||
struct pm8xxx_charger_core_data charger_cdata;
|
||||
unsigned int safety_time;
|
||||
unsigned int ttrkl_time;
|
||||
unsigned int update_time;
|
||||
unsigned int max_voltage;
|
||||
unsigned int min_voltage;
|
||||
unsigned int uvd_thresh_voltage;
|
||||
unsigned int alarm_voltage;
|
||||
unsigned int safe_current_ma;
|
||||
unsigned int alarm_low_mv;
|
||||
unsigned int alarm_high_mv;
|
||||
unsigned int resume_voltage_delta;
|
||||
int resume_charge_percent;
|
||||
unsigned int term_current;
|
||||
int cool_temp;
|
||||
int warm_temp;
|
||||
unsigned int temp_check_period;
|
||||
unsigned int max_bat_chg_current;
|
||||
unsigned int usb_max_current;
|
||||
unsigned int cool_bat_chg_current;
|
||||
unsigned int warm_bat_chg_current;
|
||||
unsigned int cool_bat_voltage;
|
||||
@@ -144,7 +169,6 @@ struct pm8921_charger_platform_data {
|
||||
int64_t batt_id_min;
|
||||
int64_t batt_id_max;
|
||||
bool keep_btm_on_suspend;
|
||||
bool dc_unplug_check;
|
||||
bool has_dc_supply;
|
||||
int trkl_voltage;
|
||||
int weak_voltage;
|
||||
@@ -157,6 +181,13 @@ struct pm8921_charger_platform_data {
|
||||
enum pm8921_chg_hot_thr hot_thr;
|
||||
int rconn_mohm;
|
||||
enum pm8921_chg_led_src_config led_src_config;
|
||||
int battery_less_hardware;
|
||||
int btc_override;
|
||||
int btc_override_cold_degc;
|
||||
int btc_override_hot_degc;
|
||||
int btc_delay_ms;
|
||||
int btc_panic_if_cant_stop_chg;
|
||||
int stop_chg_upon_expiry;
|
||||
};
|
||||
|
||||
enum pm8921_charger_source {
|
||||
@@ -169,15 +200,6 @@ enum pm8921_charger_source {
|
||||
void pm8921_charger_vbus_draw(unsigned int mA);
|
||||
int pm8921_charger_register_vbus_sn(void (*callback)(int));
|
||||
void pm8921_charger_unregister_vbus_sn(void (*callback)(int));
|
||||
/**
|
||||
* pm8921_charger_enable -
|
||||
*
|
||||
* @enable: 1 means enable charging, 0 means disable
|
||||
*
|
||||
* Enable/Disable battery charging current, the device will still draw current
|
||||
* from the charging source
|
||||
*/
|
||||
int pm8921_charger_enable(bool enable);
|
||||
|
||||
/**
|
||||
* pm8921_is_usb_chg_plugged_in - is usb plugged in
|
||||
@@ -309,10 +331,6 @@ static inline int pm8921_charger_register_vbus_sn(void (*callback)(int))
|
||||
static inline void pm8921_charger_unregister_vbus_sn(void (*callback)(int))
|
||||
{
|
||||
}
|
||||
static inline int pm8921_charger_enable(bool enable)
|
||||
{
|
||||
return -ENXIO;
|
||||
}
|
||||
static inline int pm8921_is_usb_chg_plugged_in(void)
|
||||
{
|
||||
return -ENXIO;
|
||||
|
||||
Reference in New Issue
Block a user