mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-09-21 03:43:03 +00:00
hwmon: Add pm8xxx ADC driver
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
This commit is contained in:
parent
37d05847f1
commit
3934abf514
|
@ -969,6 +969,15 @@ config SENSORS_MSM_ADC
|
|||
internally uses an array of LTC2499 and EPM ADCs in a differential
|
||||
configuration to provide a flat set of channels that can be addressed.
|
||||
|
||||
config SENSORS_PM8XXX_ADC
|
||||
tristate "Support for Qualcomm PM8XXX ADC"
|
||||
depends on MFD_PM8XXX
|
||||
help
|
||||
This is the ADC arbiter driver for Qualcomm PM8XXX Chip.
|
||||
|
||||
The driver supports reading the HKADC, XOADC and support to set and receive
|
||||
temperature threshold notifications using the Battery temperature module.
|
||||
|
||||
config SENSORS_PC87360
|
||||
tristate "National Semiconductor PC87360 family"
|
||||
depends on !PPC
|
||||
|
|
|
@ -142,6 +142,7 @@ obj-$(CONFIG_SENSORS_WM831X) += wm831x-hwmon.o
|
|||
obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o
|
||||
obj-$(CONFIG_SENSORS_WPCE775X) += wpce775x.o
|
||||
obj-$(CONFIG_SENSORS_MSM_ADC) += msm_adc.o m_adcproc.o
|
||||
obj-$(CONFIG_SENSORS_PM8XXX_ADC) += pm8xxx-adc.o pm8xxx-adc-scale.o
|
||||
|
||||
obj-$(CONFIG_PMBUS) += pmbus/
|
||||
|
||||
|
|
738
drivers/hwmon/pm8xxx-adc-scale.c
Normal file
738
drivers/hwmon/pm8xxx-adc-scale.c
Normal file
|
@ -0,0 +1,738 @@
|
|||
/*
|
||||
* Copyright (c) 2011, 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/kernel.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mfd/pm8xxx/pm8xxx-adc.h>
|
||||
#define KELVINMIL_DEGMIL 273160
|
||||
|
||||
/* Units for temperature below (on x axis) is in 0.1DegC as
|
||||
required by the battery driver. Note the resolution used
|
||||
here to compute the table was done for DegC to milli-volts.
|
||||
In consideration to limit the size of the table for the given
|
||||
temperature range below, the result is linearly interpolated
|
||||
and provided to the battery driver in the units desired for
|
||||
their framework which is 0.1DegC. True resolution of 0.1DegC
|
||||
will result in the below table size to increase by 10 times */
|
||||
static const struct pm8xxx_adc_map_pt adcmap_btm_threshold[] = {
|
||||
{-300, 1642},
|
||||
{-200, 1544},
|
||||
{-100, 1414},
|
||||
{0, 1260},
|
||||
{10, 1244},
|
||||
{20, 1228},
|
||||
{30, 1212},
|
||||
{40, 1195},
|
||||
{50, 1179},
|
||||
{60, 1162},
|
||||
{70, 1146},
|
||||
{80, 1129},
|
||||
{90, 1113},
|
||||
{100, 1097},
|
||||
{110, 1080},
|
||||
{120, 1064},
|
||||
{130, 1048},
|
||||
{140, 1032},
|
||||
{150, 1016},
|
||||
{160, 1000},
|
||||
{170, 985},
|
||||
{180, 969},
|
||||
{190, 954},
|
||||
{200, 939},
|
||||
{210, 924},
|
||||
{220, 909},
|
||||
{230, 894},
|
||||
{240, 880},
|
||||
{250, 866},
|
||||
{260, 852},
|
||||
{270, 838},
|
||||
{280, 824},
|
||||
{290, 811},
|
||||
{300, 798},
|
||||
{310, 785},
|
||||
{320, 773},
|
||||
{330, 760},
|
||||
{340, 748},
|
||||
{350, 736},
|
||||
{360, 725},
|
||||
{370, 713},
|
||||
{380, 702},
|
||||
{390, 691},
|
||||
{400, 681},
|
||||
{410, 670},
|
||||
{420, 660},
|
||||
{430, 650},
|
||||
{440, 640},
|
||||
{450, 631},
|
||||
{460, 622},
|
||||
{470, 613},
|
||||
{480, 604},
|
||||
{490, 595},
|
||||
{500, 587},
|
||||
{510, 579},
|
||||
{520, 571},
|
||||
{530, 563},
|
||||
{540, 556},
|
||||
{550, 548},
|
||||
{560, 541},
|
||||
{570, 534},
|
||||
{580, 527},
|
||||
{590, 521},
|
||||
{600, 514},
|
||||
{610, 508},
|
||||
{620, 502},
|
||||
{630, 496},
|
||||
{640, 490},
|
||||
{650, 485},
|
||||
{660, 281},
|
||||
{670, 274},
|
||||
{680, 267},
|
||||
{690, 260},
|
||||
{700, 254},
|
||||
{710, 247},
|
||||
{720, 241},
|
||||
{730, 235},
|
||||
{740, 229},
|
||||
{750, 224},
|
||||
{760, 218},
|
||||
{770, 213},
|
||||
{780, 208},
|
||||
{790, 203}
|
||||
};
|
||||
|
||||
static const struct pm8xxx_adc_map_pt adcmap_pa_therm[] = {
|
||||
{1677, -30},
|
||||
{1671, -29},
|
||||
{1663, -28},
|
||||
{1656, -27},
|
||||
{1648, -26},
|
||||
{1640, -25},
|
||||
{1632, -24},
|
||||
{1623, -23},
|
||||
{1615, -22},
|
||||
{1605, -21},
|
||||
{1596, -20},
|
||||
{1586, -19},
|
||||
{1576, -18},
|
||||
{1565, -17},
|
||||
{1554, -16},
|
||||
{1543, -15},
|
||||
{1531, -14},
|
||||
{1519, -13},
|
||||
{1507, -12},
|
||||
{1494, -11},
|
||||
{1482, -10},
|
||||
{1468, -9},
|
||||
{1455, -8},
|
||||
{1441, -7},
|
||||
{1427, -6},
|
||||
{1412, -5},
|
||||
{1398, -4},
|
||||
{1383, -3},
|
||||
{1367, -2},
|
||||
{1352, -1},
|
||||
{1336, 0},
|
||||
{1320, 1},
|
||||
{1304, 2},
|
||||
{1287, 3},
|
||||
{1271, 4},
|
||||
{1254, 5},
|
||||
{1237, 6},
|
||||
{1219, 7},
|
||||
{1202, 8},
|
||||
{1185, 9},
|
||||
{1167, 10},
|
||||
{1149, 11},
|
||||
{1131, 12},
|
||||
{1114, 13},
|
||||
{1096, 14},
|
||||
{1078, 15},
|
||||
{1060, 16},
|
||||
{1042, 17},
|
||||
{1024, 18},
|
||||
{1006, 19},
|
||||
{988, 20},
|
||||
{970, 21},
|
||||
{952, 22},
|
||||
{934, 23},
|
||||
{917, 24},
|
||||
{899, 25},
|
||||
{882, 26},
|
||||
{865, 27},
|
||||
{848, 28},
|
||||
{831, 29},
|
||||
{814, 30},
|
||||
{797, 31},
|
||||
{781, 32},
|
||||
{764, 33},
|
||||
{748, 34},
|
||||
{732, 35},
|
||||
{717, 36},
|
||||
{701, 37},
|
||||
{686, 38},
|
||||
{671, 39},
|
||||
{656, 40},
|
||||
{642, 41},
|
||||
{627, 42},
|
||||
{613, 43},
|
||||
{599, 44},
|
||||
{586, 45},
|
||||
{572, 46},
|
||||
{559, 47},
|
||||
{546, 48},
|
||||
{534, 49},
|
||||
{522, 50},
|
||||
{509, 51},
|
||||
{498, 52},
|
||||
{486, 53},
|
||||
{475, 54},
|
||||
{463, 55},
|
||||
{452, 56},
|
||||
{442, 57},
|
||||
{431, 58},
|
||||
{421, 59},
|
||||
{411, 60},
|
||||
{401, 61},
|
||||
{392, 62},
|
||||
{383, 63},
|
||||
{374, 64},
|
||||
{365, 65},
|
||||
{356, 66},
|
||||
{348, 67},
|
||||
{339, 68},
|
||||
{331, 69},
|
||||
{323, 70},
|
||||
{316, 71},
|
||||
{308, 72},
|
||||
{301, 73},
|
||||
{294, 74},
|
||||
{287, 75},
|
||||
{280, 76},
|
||||
{273, 77},
|
||||
{267, 78},
|
||||
{261, 79},
|
||||
{255, 80},
|
||||
{249, 81},
|
||||
{243, 82},
|
||||
{237, 83},
|
||||
{232, 84},
|
||||
{226, 85},
|
||||
{221, 86},
|
||||
{216, 87},
|
||||
{211, 88},
|
||||
{206, 89},
|
||||
{201, 90}
|
||||
};
|
||||
|
||||
static const struct pm8xxx_adc_map_pt adcmap_ntcg_104ef_104fb[] = {
|
||||
{696483, -40960},
|
||||
{649148, -39936},
|
||||
{605368, -38912},
|
||||
{564809, -37888},
|
||||
{527215, -36864},
|
||||
{492322, -35840},
|
||||
{460007, -34816},
|
||||
{429982, -33792},
|
||||
{402099, -32768},
|
||||
{376192, -31744},
|
||||
{352075, -30720},
|
||||
{329714, -29696},
|
||||
{308876, -28672},
|
||||
{289480, -27648},
|
||||
{271417, -26624},
|
||||
{254574, -25600},
|
||||
{238903, -24576},
|
||||
{224276, -23552},
|
||||
{210631, -22528},
|
||||
{197896, -21504},
|
||||
{186007, -20480},
|
||||
{174899, -19456},
|
||||
{164521, -18432},
|
||||
{154818, -17408},
|
||||
{145744, -16384},
|
||||
{137265, -15360},
|
||||
{129307, -14336},
|
||||
{121866, -13312},
|
||||
{114896, -12288},
|
||||
{108365, -11264},
|
||||
{102252, -10240},
|
||||
{96499, -9216},
|
||||
{91111, -8192},
|
||||
{86055, -7168},
|
||||
{81308, -6144},
|
||||
{76857, -5120},
|
||||
{72660, -4096},
|
||||
{68722, -3072},
|
||||
{65020, -2048},
|
||||
{61538, -1024},
|
||||
{58261, 0},
|
||||
{55177, 1024},
|
||||
{52274, 2048},
|
||||
{49538, 3072},
|
||||
{46962, 4096},
|
||||
{44531, 5120},
|
||||
{42243, 6144},
|
||||
{40083, 7168},
|
||||
{38045, 8192},
|
||||
{36122, 9216},
|
||||
{34308, 10240},
|
||||
{32592, 11264},
|
||||
{30972, 12288},
|
||||
{29442, 13312},
|
||||
{27995, 14336},
|
||||
{26624, 15360},
|
||||
{25333, 16384},
|
||||
{24109, 17408},
|
||||
{22951, 18432},
|
||||
{21854, 19456},
|
||||
{20807, 20480},
|
||||
{19831, 21504},
|
||||
{18899, 22528},
|
||||
{18016, 23552},
|
||||
{17178, 24576},
|
||||
{16384, 25600},
|
||||
{15631, 26624},
|
||||
{14916, 27648},
|
||||
{14237, 28672},
|
||||
{13593, 29696},
|
||||
{12976, 30720},
|
||||
{12400, 31744},
|
||||
{11848, 32768},
|
||||
{11324, 33792},
|
||||
{10825, 34816},
|
||||
{10354, 35840},
|
||||
{9900, 36864},
|
||||
{9471, 37888},
|
||||
{9062, 38912},
|
||||
{8674, 39936},
|
||||
{8306, 40960},
|
||||
{7951, 41984},
|
||||
{7616, 43008},
|
||||
{7296, 44032},
|
||||
{6991, 45056},
|
||||
{6701, 46080},
|
||||
{6424, 47104},
|
||||
{6160, 48128},
|
||||
{5908, 49152},
|
||||
{5667, 50176},
|
||||
{5439, 51200},
|
||||
{5219, 52224},
|
||||
{5010, 53248},
|
||||
{4810, 54272},
|
||||
{4619, 55296},
|
||||
{4440, 56320},
|
||||
{4263, 57344},
|
||||
{4097, 58368},
|
||||
{3938, 59392},
|
||||
{3785, 60416},
|
||||
{3637, 61440},
|
||||
{3501, 62464},
|
||||
{3368, 63488},
|
||||
{3240, 64512},
|
||||
{3118, 65536},
|
||||
{2998, 66560},
|
||||
{2889, 67584},
|
||||
{2782, 68608},
|
||||
{2680, 69632},
|
||||
{2581, 70656},
|
||||
{2490, 71680},
|
||||
{2397, 72704},
|
||||
{2310, 73728},
|
||||
{2227, 74752},
|
||||
{2147, 75776},
|
||||
{2064, 76800},
|
||||
{1998, 77824},
|
||||
{1927, 78848},
|
||||
{1860, 79872},
|
||||
{1795, 80896},
|
||||
{1736, 81920},
|
||||
{1673, 82944},
|
||||
{1615, 83968},
|
||||
{1560, 84992},
|
||||
{1507, 86016},
|
||||
{1456, 87040},
|
||||
{1407, 88064},
|
||||
{1360, 89088},
|
||||
{1314, 90112},
|
||||
{1271, 91136},
|
||||
{1228, 92160},
|
||||
{1189, 93184},
|
||||
{1150, 94208},
|
||||
{1112, 95232},
|
||||
{1076, 96256},
|
||||
{1042, 97280},
|
||||
{1008, 98304},
|
||||
{976, 99328},
|
||||
{945, 100352},
|
||||
{915, 101376},
|
||||
{886, 102400},
|
||||
{859, 103424},
|
||||
{832, 104448},
|
||||
{807, 105472},
|
||||
{782, 106496},
|
||||
{756, 107520},
|
||||
{735, 108544},
|
||||
{712, 109568},
|
||||
{691, 110592},
|
||||
{670, 111616},
|
||||
{650, 112640},
|
||||
{631, 113664},
|
||||
{612, 114688},
|
||||
{594, 115712},
|
||||
{577, 116736},
|
||||
{560, 117760},
|
||||
{544, 118784},
|
||||
{528, 119808},
|
||||
{513, 120832},
|
||||
{498, 121856},
|
||||
{483, 122880},
|
||||
{470, 123904},
|
||||
{457, 124928},
|
||||
{444, 125952},
|
||||
{431, 126976},
|
||||
{419, 128000}
|
||||
};
|
||||
|
||||
static int32_t pm8xxx_adc_map_linear(const struct pm8xxx_adc_map_pt *pts,
|
||||
uint32_t tablesize, int32_t input, int64_t *output)
|
||||
{
|
||||
bool descending = 1;
|
||||
uint32_t i = 0;
|
||||
|
||||
if ((pts == NULL) || (output == NULL))
|
||||
return -EINVAL;
|
||||
|
||||
/* Check if table is descending or ascending */
|
||||
if (tablesize > 1) {
|
||||
if (pts[0].x < pts[1].x)
|
||||
descending = 0;
|
||||
}
|
||||
|
||||
while (i < tablesize) {
|
||||
if ((descending == 1) && (pts[i].x < input)) {
|
||||
/* table entry is less than measured
|
||||
value and table is descending, stop */
|
||||
break;
|
||||
} else if ((descending == 0) &&
|
||||
(pts[i].x > input)) {
|
||||
/* table entry is greater than measured
|
||||
value and table is ascending, stop */
|
||||
break;
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == 0)
|
||||
*output = pts[0].y;
|
||||
else if (i == tablesize)
|
||||
*output = pts[tablesize-1].y;
|
||||
else {
|
||||
/* result is between search_index and search_index-1 */
|
||||
/* interpolate linearly */
|
||||
*output = (((int32_t) ((pts[i].y - pts[i-1].y)*
|
||||
(input - pts[i-1].x))/
|
||||
(pts[i].x - pts[i-1].x))+
|
||||
pts[i-1].y);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t pm8xxx_adc_map_batt_therm(const struct pm8xxx_adc_map_pt *pts,
|
||||
uint32_t tablesize, int32_t input, int64_t *output)
|
||||
{
|
||||
bool descending = 1;
|
||||
uint32_t i = 0;
|
||||
|
||||
if ((pts == NULL) || (output == NULL))
|
||||
return -EINVAL;
|
||||
|
||||
/* Check if table is descending or ascending */
|
||||
if (tablesize > 1) {
|
||||
if (pts[0].y < pts[1].y)
|
||||
descending = 0;
|
||||
}
|
||||
|
||||
while (i < tablesize) {
|
||||
if ((descending == 1) && (pts[i].y < input)) {
|
||||
/* table entry is less than measured
|
||||
value and table is descending, stop */
|
||||
break;
|
||||
} else if ((descending == 0) && (pts[i].y > input)) {
|
||||
/* table entry is greater than measured
|
||||
value and table is ascending, stop */
|
||||
break;
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
*output = pts[0].x;
|
||||
} else if (i == tablesize) {
|
||||
*output = pts[tablesize-1].x;
|
||||
} else {
|
||||
/* result is between search_index and search_index-1 */
|
||||
/* interpolate linearly */
|
||||
*output = (((int32_t) ((pts[i].x - pts[i-1].x)*
|
||||
(input - pts[i-1].y))/
|
||||
(pts[i].y - pts[i-1].y))+
|
||||
pts[i-1].x);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t pm8xxx_adc_scale_default(int32_t adc_code,
|
||||
const struct pm8xxx_adc_properties *adc_properties,
|
||||
const struct pm8xxx_adc_chan_properties *chan_properties,
|
||||
struct pm8xxx_adc_chan_result *adc_chan_result)
|
||||
{
|
||||
bool negative_rawfromoffset = 0, negative_offset = 0;
|
||||
int64_t scale_voltage = 0;
|
||||
|
||||
if (!chan_properties || !chan_properties->offset_gain_numerator ||
|
||||
!chan_properties->offset_gain_denominator || !adc_properties
|
||||
|| !adc_chan_result)
|
||||
return -EINVAL;
|
||||
|
||||
scale_voltage = (adc_code -
|
||||
chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].adc_gnd)
|
||||
* chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].dx;
|
||||
if (scale_voltage < 0) {
|
||||
negative_offset = 1;
|
||||
scale_voltage = -scale_voltage;
|
||||
}
|
||||
do_div(scale_voltage,
|
||||
chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].dy);
|
||||
if (negative_offset)
|
||||
scale_voltage = -scale_voltage;
|
||||
scale_voltage += chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].dx;
|
||||
|
||||
if (scale_voltage < 0) {
|
||||
if (adc_properties->bipolar) {
|
||||
scale_voltage = -scale_voltage;
|
||||
negative_rawfromoffset = 1;
|
||||
} else {
|
||||
scale_voltage = 0;
|
||||
}
|
||||
}
|
||||
|
||||
adc_chan_result->measurement = scale_voltage *
|
||||
chan_properties->offset_gain_denominator;
|
||||
|
||||
/* do_div only perform positive integer division! */
|
||||
do_div(adc_chan_result->measurement,
|
||||
chan_properties->offset_gain_numerator);
|
||||
|
||||
if (negative_rawfromoffset)
|
||||
adc_chan_result->measurement = -adc_chan_result->measurement;
|
||||
|
||||
/* Note: adc_chan_result->measurement is in the unit of
|
||||
* adc_properties.adc_reference. For generic channel processing,
|
||||
* channel measurement is a scale/ratio relative to the adc
|
||||
* reference input */
|
||||
adc_chan_result->physical = adc_chan_result->measurement;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pm8xxx_adc_scale_default);
|
||||
|
||||
static int64_t pm8xxx_adc_scale_ratiometric_calib(int32_t adc_code,
|
||||
const struct pm8xxx_adc_properties *adc_properties,
|
||||
const struct pm8xxx_adc_chan_properties *chan_properties)
|
||||
{
|
||||
int64_t adc_voltage = 0;
|
||||
bool negative_offset = 0;
|
||||
|
||||
if (!chan_properties || !chan_properties->offset_gain_numerator ||
|
||||
!chan_properties->offset_gain_denominator || !adc_properties)
|
||||
return -EINVAL;
|
||||
|
||||
adc_voltage = (adc_code -
|
||||
chan_properties->adc_graph[ADC_CALIB_RATIOMETRIC].adc_gnd)
|
||||
* adc_properties->adc_vdd_reference;
|
||||
if (adc_voltage < 0) {
|
||||
negative_offset = 1;
|
||||
adc_voltage = -adc_voltage;
|
||||
}
|
||||
do_div(adc_voltage,
|
||||
chan_properties->adc_graph[ADC_CALIB_RATIOMETRIC].dy);
|
||||
if (negative_offset)
|
||||
adc_voltage = -adc_voltage;
|
||||
|
||||
return adc_voltage;
|
||||
}
|
||||
|
||||
int32_t pm8xxx_adc_scale_batt_therm(int32_t adc_code,
|
||||
const struct pm8xxx_adc_properties *adc_properties,
|
||||
const struct pm8xxx_adc_chan_properties *chan_properties,
|
||||
struct pm8xxx_adc_chan_result *adc_chan_result)
|
||||
{
|
||||
int64_t bat_voltage = 0;
|
||||
|
||||
bat_voltage = pm8xxx_adc_scale_ratiometric_calib(adc_code,
|
||||
adc_properties, chan_properties);
|
||||
|
||||
return pm8xxx_adc_map_batt_therm(
|
||||
adcmap_btm_threshold,
|
||||
ARRAY_SIZE(adcmap_btm_threshold),
|
||||
bat_voltage,
|
||||
&adc_chan_result->physical);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pm8xxx_adc_scale_batt_therm);
|
||||
|
||||
int32_t pm8xxx_adc_scale_pa_therm(int32_t adc_code,
|
||||
const struct pm8xxx_adc_properties *adc_properties,
|
||||
const struct pm8xxx_adc_chan_properties *chan_properties,
|
||||
struct pm8xxx_adc_chan_result *adc_chan_result)
|
||||
{
|
||||
int64_t pa_voltage = 0;
|
||||
|
||||
pa_voltage = pm8xxx_adc_scale_ratiometric_calib(adc_code,
|
||||
adc_properties, chan_properties);
|
||||
|
||||
return pm8xxx_adc_map_linear(
|
||||
adcmap_pa_therm,
|
||||
ARRAY_SIZE(adcmap_pa_therm),
|
||||
pa_voltage,
|
||||
&adc_chan_result->physical);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pm8xxx_adc_scale_pa_therm);
|
||||
|
||||
int32_t pm8xxx_adc_scale_batt_id(int32_t adc_code,
|
||||
const struct pm8xxx_adc_properties *adc_properties,
|
||||
const struct pm8xxx_adc_chan_properties *chan_properties,
|
||||
struct pm8xxx_adc_chan_result *adc_chan_result)
|
||||
{
|
||||
int64_t batt_id_voltage = 0;
|
||||
|
||||
batt_id_voltage = pm8xxx_adc_scale_ratiometric_calib(adc_code,
|
||||
adc_properties, chan_properties);
|
||||
adc_chan_result->physical = batt_id_voltage;
|
||||
adc_chan_result->physical = adc_chan_result->measurement;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pm8xxx_adc_scale_batt_id);
|
||||
|
||||
int32_t pm8xxx_adc_scale_pmic_therm(int32_t adc_code,
|
||||
const struct pm8xxx_adc_properties *adc_properties,
|
||||
const struct pm8xxx_adc_chan_properties *chan_properties,
|
||||
struct pm8xxx_adc_chan_result *adc_chan_result)
|
||||
{
|
||||
int64_t pmic_voltage = 0;
|
||||
bool negative_offset = 0;
|
||||
|
||||
if (!chan_properties || !chan_properties->offset_gain_numerator ||
|
||||
!chan_properties->offset_gain_denominator || !adc_properties
|
||||
|| !adc_chan_result)
|
||||
return -EINVAL;
|
||||
|
||||
pmic_voltage = (adc_code -
|
||||
chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].adc_gnd)
|
||||
* chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].dx;
|
||||
if (pmic_voltage < 0) {
|
||||
negative_offset = 1;
|
||||
pmic_voltage = -pmic_voltage;
|
||||
}
|
||||
do_div(pmic_voltage,
|
||||
chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].dy);
|
||||
if (negative_offset)
|
||||
pmic_voltage = -pmic_voltage;
|
||||
pmic_voltage += chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].dx;
|
||||
|
||||
if (pmic_voltage > 0) {
|
||||
/* 2mV/K */
|
||||
adc_chan_result->measurement = pmic_voltage*
|
||||
chan_properties->offset_gain_denominator;
|
||||
|
||||
do_div(adc_chan_result->measurement,
|
||||
chan_properties->offset_gain_numerator * 2);
|
||||
} else {
|
||||
adc_chan_result->measurement = 0;
|
||||
}
|
||||
/* Change to .001 deg C */
|
||||
adc_chan_result->measurement -= KELVINMIL_DEGMIL;
|
||||
adc_chan_result->physical = (int32_t)adc_chan_result->measurement;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pm8xxx_adc_scale_pmic_therm);
|
||||
|
||||
/* Scales the ADC code to 0.001 degrees C using the map
|
||||
* table for the XO thermistor.
|
||||
*/
|
||||
int32_t pm8xxx_adc_tdkntcg_therm(int32_t adc_code,
|
||||
const struct pm8xxx_adc_properties *adc_properties,
|
||||
const struct pm8xxx_adc_chan_properties *chan_properties,
|
||||
struct pm8xxx_adc_chan_result *adc_chan_result)
|
||||
{
|
||||
int64_t xo_thm = 0;
|
||||
|
||||
if (!chan_properties || !chan_properties->offset_gain_numerator ||
|
||||
!chan_properties->offset_gain_denominator || !adc_properties
|
||||
|| !adc_chan_result)
|
||||
return -EINVAL;
|
||||
|
||||
xo_thm = pm8xxx_adc_scale_ratiometric_calib(adc_code,
|
||||
adc_properties, chan_properties);
|
||||
xo_thm <<= 4;
|
||||
pm8xxx_adc_map_linear(adcmap_ntcg_104ef_104fb,
|
||||
ARRAY_SIZE(adcmap_ntcg_104ef_104fb),
|
||||
xo_thm, &adc_chan_result->physical);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pm8xxx_adc_tdkntcg_therm);
|
||||
|
||||
int32_t pm8xxx_adc_batt_scaler(struct pm8xxx_adc_arb_btm_param *btm_param,
|
||||
const struct pm8xxx_adc_properties *adc_properties,
|
||||
const struct pm8xxx_adc_chan_properties *chan_properties)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = pm8xxx_adc_map_linear(
|
||||
adcmap_btm_threshold,
|
||||
ARRAY_SIZE(adcmap_btm_threshold),
|
||||
(btm_param->low_thr_temp),
|
||||
&btm_param->low_thr_voltage);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
btm_param->low_thr_voltage *=
|
||||
chan_properties->adc_graph[ADC_CALIB_RATIOMETRIC].dy;
|
||||
do_div(btm_param->low_thr_voltage, adc_properties->adc_vdd_reference);
|
||||
btm_param->low_thr_voltage +=
|
||||
chan_properties->adc_graph[ADC_CALIB_RATIOMETRIC].adc_gnd;
|
||||
|
||||
rc = pm8xxx_adc_map_linear(
|
||||
adcmap_btm_threshold,
|
||||
ARRAY_SIZE(adcmap_btm_threshold),
|
||||
(btm_param->high_thr_temp),
|
||||
&btm_param->high_thr_voltage);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
btm_param->high_thr_voltage *=
|
||||
chan_properties->adc_graph[ADC_CALIB_RATIOMETRIC].dy;
|
||||
do_div(btm_param->high_thr_voltage, adc_properties->adc_vdd_reference);
|
||||
btm_param->high_thr_voltage +=
|
||||
chan_properties->adc_graph[ADC_CALIB_RATIOMETRIC].adc_gnd;
|
||||
|
||||
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pm8xxx_adc_batt_scaler);
|
1307
drivers/hwmon/pm8xxx-adc.c
Normal file
1307
drivers/hwmon/pm8xxx-adc.c
Normal file
File diff suppressed because it is too large
Load diff
604
include/linux/mfd/pm8xxx/pm8xxx-adc.h
Normal file
604
include/linux/mfd/pm8xxx/pm8xxx-adc.h
Normal file
|
@ -0,0 +1,604 @@
|
|||
/*
|
||||
* Copyright (c) 2011-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.
|
||||
*/
|
||||
/*
|
||||
* Qualcomm PMIC 8921/8018 ADC driver header file
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __PM8XXX_ADC_H
|
||||
#define __PM8XXX_ADC_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
/**
|
||||
* enum pm8xxx_adc_channels - PM8XXX AMUX arbiter channels
|
||||
* %CHANNEL_VCOIN: Backup voltage for certain register set
|
||||
* %CHANNEL_VBAT: Battery voltage
|
||||
* %CHANNEL_DCIN: Charger input voltage without internal OVP
|
||||
* %CHANNEL_ICHG: Charge-current monitor
|
||||
* %CHANNEL_VPH_PWR: Main system power
|
||||
* %CHANNEL_IBAT: Battery charge current
|
||||
* %CHANNEL_MPP_1: 16:1 pre-mux unity scale MPP input
|
||||
* %CHANNEL_MPP_2: 16:1 pre-mux 1/3 scale MPP input
|
||||
* %CHANNEL_BATT_THERM: Battery temperature
|
||||
* %CHANNEL_BATT_ID: Battery detection
|
||||
* %CHANNEL_USBIN: Charger input voltage with internal OVP
|
||||
* %CHANNEL_DIE_TEMP: Pmic_die temperature
|
||||
* %CHANNEL_625MV: 625mv reference channel
|
||||
* %CHANNEL_125V: 1.25v reference channel
|
||||
* %CHANNEL_CHG_TEMP: Charger temperature
|
||||
* %CHANNEL_MUXOFF: Channel to reduce input load on the mux
|
||||
* %CHANNEL_NONE: Do not use this channel
|
||||
*/
|
||||
enum pm8xxx_adc_channels {
|
||||
CHANNEL_VCOIN = 0,
|
||||
CHANNEL_VBAT,
|
||||
CHANNEL_DCIN,
|
||||
CHANNEL_ICHG,
|
||||
CHANNEL_VPH_PWR,
|
||||
CHANNEL_IBAT,
|
||||
CHANNEL_MPP_1,
|
||||
CHANNEL_MPP_2,
|
||||
CHANNEL_BATT_THERM,
|
||||
/* PM8018 ADC Arbiter uses a single channel on AMUX8
|
||||
* to read either Batt_id or Batt_therm.
|
||||
*/
|
||||
CHANNEL_BATT_ID_THERM = CHANNEL_BATT_THERM,
|
||||
CHANNEL_BATT_ID,
|
||||
CHANNEL_USBIN,
|
||||
CHANNEL_DIE_TEMP,
|
||||
CHANNEL_625MV,
|
||||
CHANNEL_125V,
|
||||
CHANNEL_CHG_TEMP,
|
||||
CHANNEL_MUXOFF,
|
||||
CHANNEL_NONE,
|
||||
ADC_MPP_1_ATEST_8 = 20,
|
||||
ADC_MPP_1_USB_SNS_DIV20,
|
||||
ADC_MPP_1_DCIN_SNS_DIV20,
|
||||
ADC_MPP_1_AMUX3,
|
||||
ADC_MPP_1_AMUX4,
|
||||
ADC_MPP_1_AMUX5,
|
||||
ADC_MPP_1_AMUX6,
|
||||
ADC_MPP_1_AMUX7,
|
||||
ADC_MPP_1_AMUX8,
|
||||
ADC_MPP_1_ATEST_1,
|
||||
ADC_MPP_1_ATEST_2,
|
||||
ADC_MPP_1_ATEST_3,
|
||||
ADC_MPP_1_ATEST_4,
|
||||
ADC_MPP_1_ATEST_5,
|
||||
ADC_MPP_1_ATEST_6,
|
||||
ADC_MPP_1_ATEST_7,
|
||||
ADC_MPP_2_ATEST_8 = 40,
|
||||
ADC_MPP_2_USB_SNS_DIV20,
|
||||
ADC_MPP_2_DCIN_SNS_DIV20,
|
||||
ADC_MPP_2_AMUX3,
|
||||
ADC_MPP_2_AMUX4,
|
||||
ADC_MPP_2_AMUX5,
|
||||
ADC_MPP_2_AMUX6,
|
||||
ADC_MPP_2_AMUX7,
|
||||
ADC_MPP_2_AMUX8,
|
||||
ADC_MPP_2_ATEST_1,
|
||||
ADC_MPP_2_ATEST_2,
|
||||
ADC_MPP_2_ATEST_3,
|
||||
ADC_MPP_2_ATEST_4,
|
||||
ADC_MPP_2_ATEST_5,
|
||||
ADC_MPP_2_ATEST_6,
|
||||
ADC_MPP_2_ATEST_7,
|
||||
ADC_CHANNEL_MAX_NUM,
|
||||
};
|
||||
|
||||
#define PM8XXX_ADC_PMIC_0 0x0
|
||||
|
||||
#define PM8XXX_CHANNEL_ADC_625_UV 625000
|
||||
#define PM8XXX_CHANNEL_MPP_SCALE1_IDX 20
|
||||
#define PM8XXX_CHANNEL_MPP_SCALE3_IDX 40
|
||||
|
||||
#define PM8XXX_AMUX_MPP_3 0x3
|
||||
#define PM8XXX_AMUX_MPP_4 0x4
|
||||
#define PM8XXX_AMUX_MPP_5 0x5
|
||||
#define PM8XXX_AMUX_MPP_6 0x6
|
||||
#define PM8XXX_AMUX_MPP_7 0x7
|
||||
#define PM8XXX_AMUX_MPP_8 0x8
|
||||
|
||||
#define PM8XXX_ADC_DEV_NAME "pm8xxx-adc"
|
||||
|
||||
/**
|
||||
* enum pm8xxx_adc_decimation_type - Sampling rate supported
|
||||
* %ADC_DECIMATION_TYPE1: 512
|
||||
* %ADC_DECIMATION_TYPE2: 1K
|
||||
* %ADC_DECIMATION_TYPE3: 2K
|
||||
* %ADC_DECIMATION_TYPE4: 4k
|
||||
* %ADC_DECIMATION_NONE: Do not use this Sampling type
|
||||
*
|
||||
* The Sampling rate is specific to each channel of the PM8XXX ADC arbiter.
|
||||
*/
|
||||
enum pm8xxx_adc_decimation_type {
|
||||
ADC_DECIMATION_TYPE1 = 0,
|
||||
ADC_DECIMATION_TYPE2,
|
||||
ADC_DECIMATION_TYPE3,
|
||||
ADC_DECIMATION_TYPE4,
|
||||
ADC_DECIMATION_NONE,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum pm8xxx_adc_calib_type - PM8XXX ADC Calibration type
|
||||
* %ADC_CALIB_ABSOLUTE: Use 625mV and 1.25V reference channels
|
||||
* %ADC_CALIB_RATIOMETRIC: Use reference Voltage/GND
|
||||
* %ADC_CALIB_CONFIG_NONE: Do not use this calibration type
|
||||
*
|
||||
* Use the input reference voltage depending on the calibration type
|
||||
* to calcluate the offset and gain parameters. The calibration is
|
||||
* specific to each channel of the PM8XXX ADC.
|
||||
*/
|
||||
enum pm8xxx_adc_calib_type {
|
||||
ADC_CALIB_ABSOLUTE = 0,
|
||||
ADC_CALIB_RATIOMETRIC,
|
||||
ADC_CALIB_NONE,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum pm8xxx_adc_channel_scaling_param - pre-scaling AMUX ratio
|
||||
* %CHAN_PATH_SCALING1: ratio of {1, 1}
|
||||
* %CHAN_PATH_SCALING2: ratio of {1, 3}
|
||||
* %CHAN_PATH_SCALING3: ratio of {1, 4}
|
||||
* %CHAN_PATH_SCALING4: ratio of {1, 6}
|
||||
* %CHAN_PATH_NONE: Do not use this pre-scaling ratio type
|
||||
*
|
||||
* The pre-scaling is applied for signals to be within the voltage range
|
||||
* of the ADC.
|
||||
*/
|
||||
enum pm8xxx_adc_channel_scaling_param {
|
||||
CHAN_PATH_SCALING1 = 0,
|
||||
CHAN_PATH_SCALING2,
|
||||
CHAN_PATH_SCALING3,
|
||||
CHAN_PATH_SCALING4,
|
||||
CHAN_PATH_SCALING_NONE,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum pm8xxx_adc_amux_input_rsv - HK/XOADC reference voltage
|
||||
* %AMUX_RSV0: XO_IN/XOADC_GND
|
||||
* %AMUX_RSV1: PMIC_IN/XOADC_GND
|
||||
* %AMUX_RSV2: PMIC_IN/BMS_CSP
|
||||
* %AMUX_RSV3: not used
|
||||
* %AMUX_RSV4: XOADC_GND/XOADC_GND
|
||||
* %AMUX_RSV5: XOADC_VREF/XOADC_GND
|
||||
* %AMUX_NONE: Do not use this input reference voltage selection
|
||||
*/
|
||||
enum pm8xxx_adc_amux_input_rsv {
|
||||
AMUX_RSV0 = 0,
|
||||
AMUX_RSV1,
|
||||
AMUX_RSV2,
|
||||
AMUX_RSV3,
|
||||
AMUX_RSV4,
|
||||
AMUX_RSV5,
|
||||
AMUX_NONE,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum pm8xxx_adc_premux_mpp_scale_type - 16:1 pre-mux scale ratio
|
||||
* %PREMUX_MPP_SCALE_0: No scaling to the input signal
|
||||
* %PREMUX_MPP_SCALE_1: Unity scaling selected by the user for MPP input
|
||||
* %PREMUX_MPP_SCALE_1_DIV3: 1/3 pre-scale to the input MPP signal
|
||||
* %PREMUX_MPP_NONE: Do not use this pre-scale mpp type
|
||||
*/
|
||||
enum pm8xxx_adc_premux_mpp_scale_type {
|
||||
PREMUX_MPP_SCALE_0 = 0,
|
||||
PREMUX_MPP_SCALE_1,
|
||||
PREMUX_MPP_SCALE_1_DIV3,
|
||||
PREMUX_MPP_NONE,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum pm8xxx_adc_scale_fn_type - Scaling function for pm8921 pre calibrated
|
||||
* digital data relative to ADC reference
|
||||
* %ADC_SCALE_DEFAULT: Default scaling to convert raw adc code to voltage
|
||||
* %ADC_SCALE_BATT_THERM: Conversion to temperature based on btm parameters
|
||||
* %ADC_SCALE_PMIC_THERM: Returns result in milli degree's Centigrade
|
||||
* %ADC_SCALE_XTERN_CHGR_CUR: Returns current across 0.1 ohm resistor
|
||||
* %ADC_SCALE_XOTHERM: Returns XO thermistor voltage in degree's Centigrade
|
||||
* %ADC_SCALE_NONE: Do not use this scaling type
|
||||
*/
|
||||
enum pm8xxx_adc_scale_fn_type {
|
||||
ADC_SCALE_DEFAULT = 0,
|
||||
ADC_SCALE_BATT_THERM,
|
||||
ADC_SCALE_PA_THERM,
|
||||
ADC_SCALE_PMIC_THERM,
|
||||
ADC_SCALE_XOTHERM,
|
||||
ADC_SCALE_NONE,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pm8xxx_adc_linear_graph - Represent ADC characteristics
|
||||
* @dy: Numerator slope to calculate the gain
|
||||
* @dx: Denominator slope to calculate the gain
|
||||
* @adc_vref: A/D word of the voltage reference used for the channel
|
||||
* @adc_gnd: A/D word of the ground reference used for the channel
|
||||
*
|
||||
* Each ADC device has different offset and gain parameters which are computed
|
||||
* to calibrate the device.
|
||||
*/
|
||||
struct pm8xxx_adc_linear_graph {
|
||||
int64_t dy;
|
||||
int64_t dx;
|
||||
int64_t adc_vref;
|
||||
int64_t adc_gnd;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pm8xxx_adc_map_pt - Map the graph representation for ADC channel
|
||||
* @x: Represent the ADC digitized code
|
||||
* @y: Represent the physical data which can be temperature, voltage,
|
||||
* resistance
|
||||
*/
|
||||
struct pm8xxx_adc_map_pt {
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pm8xxx_adc_scaling_ratio - Represent scaling ratio for adc input
|
||||
* @num: Numerator scaling parameter
|
||||
* @den: Denominator scaling parameter
|
||||
*/
|
||||
struct pm8xxx_adc_scaling_ratio {
|
||||
int32_t num;
|
||||
int32_t den;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pm8xxx_adc_properties - Represent the ADC properties
|
||||
* @adc_reference: Reference voltage for PM8XXX ADC
|
||||
* @bitresolution: ADC bit resolution for PM8XXX ADC
|
||||
* @biploar: Polarity for PM8XXX ADC
|
||||
*/
|
||||
struct pm8xxx_adc_properties {
|
||||
uint32_t adc_vdd_reference;
|
||||
uint32_t bitresolution;
|
||||
bool bipolar;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pm8xxx_adc_chan_properties - Represent channel properties of the ADC
|
||||
* @offset_gain_numerator: The inverse numerator of the gain applied to the
|
||||
* input channel
|
||||
* @offset_gain_denominator: The inverse denominator of the gain applied to the
|
||||
* input channel
|
||||
* @adc_graph: ADC graph for the channel of struct type pm8xxx_adc_linear_graph
|
||||
*/
|
||||
struct pm8xxx_adc_chan_properties {
|
||||
uint32_t offset_gain_numerator;
|
||||
uint32_t offset_gain_denominator;
|
||||
struct pm8xxx_adc_linear_graph adc_graph[2];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pm8xxx_adc_chan_result - Represent the result of the PM8XXX ADC
|
||||
* @chan: The channel number of the requested conversion
|
||||
* @adc_code: The pre-calibrated digital output of a given ADC relative to the
|
||||
* the ADC reference
|
||||
* @measurement: In units specific for a given ADC; most ADC uses reference
|
||||
* voltage but some ADC uses reference current. This measurement
|
||||
* here is a number relative to a reference of a given ADC
|
||||
* @physical: The data meaningful for each individual channel whether it is
|
||||
* voltage, current, temperature, etc.
|
||||
* All voltage units are represented in micro - volts.
|
||||
* -Battery temperature units are represented as 0.1 DegC
|
||||
* -PA Therm temperature units are represented as DegC
|
||||
* -PMIC Die temperature units are represented as 0.001 DegC
|
||||
*/
|
||||
struct pm8xxx_adc_chan_result {
|
||||
uint32_t chan;
|
||||
int32_t adc_code;
|
||||
int64_t measurement;
|
||||
int64_t physical;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_SENSORS_PM8XXX_ADC) \
|
||||
|| defined(CONFIG_SENSORS_PM8XXX_ADC_MODULE)
|
||||
/**
|
||||
* pm8xxx_adc_scale_default() - Scales the pre-calibrated digital output
|
||||
* of an ADC to the ADC reference and compensates for the
|
||||
* gain and offset.
|
||||
* @adc_code: pre-calibrated digital ouput of the ADC.
|
||||
* @adc_prop: adc properties of the pm8xxx adc such as bit resolution,
|
||||
* reference voltage.
|
||||
* @chan_prop: individual channel properties to compensate the i/p scaling,
|
||||
* slope and offset.
|
||||
* @chan_rslt: Physical result to be stored.
|
||||
*/
|
||||
int32_t pm8xxx_adc_scale_default(int32_t adc_code,
|
||||
const struct pm8xxx_adc_properties *adc_prop,
|
||||
const struct pm8xxx_adc_chan_properties *chan_prop,
|
||||
struct pm8xxx_adc_chan_result *chan_rslt);
|
||||
/**
|
||||
* pm8xxx_adc_scale_tdkntcg_therm() - Scales the pre-calibrated digital output
|
||||
* of an ADC to the ADC reference and compensates for the
|
||||
* gain and offset. Returns the temperature of the xo therm in mili
|
||||
degC.
|
||||
* @adc_code: pre-calibrated digital ouput of the ADC.
|
||||
* @adc_prop: adc properties of the pm8xxx adc such as bit resolution,
|
||||
* reference voltage.
|
||||
* @chan_prop: individual channel properties to compensate the i/p scaling,
|
||||
* slope and offset.
|
||||
* @chan_rslt: physical result to be stored.
|
||||
*/
|
||||
int32_t pm8xxx_adc_tdkntcg_therm(int32_t adc_code,
|
||||
const struct pm8xxx_adc_properties *adc_prop,
|
||||
const struct pm8xxx_adc_chan_properties *chan_prop,
|
||||
struct pm8xxx_adc_chan_result *chan_rslt);
|
||||
/**
|
||||
* pm8xxx_adc_scale_batt_therm() - Scales the pre-calibrated digital output
|
||||
* of an ADC to the ADC reference and compensates for the
|
||||
* gain and offset. Returns the temperature in degC.
|
||||
* @adc_code: pre-calibrated digital ouput of the ADC.
|
||||
* @adc_prop: adc properties of the pm8xxx adc such as bit resolution,
|
||||
* reference voltage.
|
||||
* @chan_prop: individual channel properties to compensate the i/p scaling,
|
||||
* slope and offset.
|
||||
* @chan_rslt: physical result to be stored.
|
||||
*/
|
||||
int32_t pm8xxx_adc_scale_batt_therm(int32_t adc_code,
|
||||
const struct pm8xxx_adc_properties *adc_prop,
|
||||
const struct pm8xxx_adc_chan_properties *chan_prop,
|
||||
struct pm8xxx_adc_chan_result *chan_rslt);
|
||||
/**
|
||||
* pm8xxx_adc_scale_pa_therm() - Scales the pre-calibrated digital output
|
||||
* of an ADC to the ADC reference and compensates for the
|
||||
* gain and offset. Returns the temperature in degC.
|
||||
* @adc_code: pre-calibrated digital ouput of the ADC.
|
||||
* @adc_prop: adc properties of the pm8xxx adc such as bit resolution,
|
||||
* reference voltage.
|
||||
* @chan_prop: individual channel properties to compensate the i/p scaling,
|
||||
* slope and offset.
|
||||
* @chan_rslt: physical result to be stored.
|
||||
*/
|
||||
int32_t pm8xxx_adc_scale_pa_therm(int32_t adc_code,
|
||||
const struct pm8xxx_adc_properties *adc_prop,
|
||||
const struct pm8xxx_adc_chan_properties *chan_prop,
|
||||
struct pm8xxx_adc_chan_result *chan_rslt);
|
||||
/**
|
||||
* pm8xxx_adc_scale_pmic_therm() - Scales the pre-calibrated digital output
|
||||
* of an ADC to the ADC reference and compensates for the
|
||||
* gain and offset. Performs the AMUX out as 2mv/K and returns
|
||||
* the temperature in mili degC.
|
||||
* @adc_code: pre-calibrated digital ouput of the ADC.
|
||||
* @adc_prop: adc properties of the pm8xxx adc such as bit resolution,
|
||||
* reference voltage.
|
||||
* @chan_prop: individual channel properties to compensate the i/p scaling,
|
||||
* slope and offset.
|
||||
* @chan_rslt: physical result to be stored.
|
||||
*/
|
||||
int32_t pm8xxx_adc_scale_pmic_therm(int32_t adc_code,
|
||||
const struct pm8xxx_adc_properties *adc_prop,
|
||||
const struct pm8xxx_adc_chan_properties *chan_prop,
|
||||
struct pm8xxx_adc_chan_result *chan_rslt);
|
||||
/**
|
||||
* pm8xxx_adc_scale_batt_id() - Scales the pre-calibrated digital output
|
||||
* of an ADC to the ADC reference and compensates for the
|
||||
* gain and offset.
|
||||
* @adc_code: pre-calibrated digital ouput of the ADC.
|
||||
* @adc_prop: adc properties of the pm8xxx adc such as bit resolution,
|
||||
* reference voltage.
|
||||
* @chan_prop: individual channel properties to compensate the i/p scaling,
|
||||
* slope and offset.
|
||||
* @chan_rslt: physical result to be stored.
|
||||
*/
|
||||
int32_t pm8xxx_adc_scale_batt_id(int32_t adc_code,
|
||||
const struct pm8xxx_adc_properties *adc_prop,
|
||||
const struct pm8xxx_adc_chan_properties *chan_prop,
|
||||
struct pm8xxx_adc_chan_result *chan_rslt);
|
||||
#else
|
||||
static inline int32_t pm8xxx_adc_scale_default(int32_t adc_code,
|
||||
const struct pm8xxx_adc_properties *adc_prop,
|
||||
const struct pm8xxx_adc_chan_properties *chan_prop,
|
||||
struct pm8xxx_adc_chan_result *chan_rslt)
|
||||
{ return -ENXIO; }
|
||||
static inline int32_t pm8xxx_adc_tdkntcg_therm(int32_t adc_code,
|
||||
const struct pm8xxx_adc_properties *adc_prop,
|
||||
const struct pm8xxx_adc_chan_properties *chan_prop,
|
||||
struct pm8xxx_adc_chan_result *chan_rslt)
|
||||
{ return -ENXIO; }
|
||||
static inline int32_t pm8xxx_adc_scale_batt_therm(int32_t adc_code,
|
||||
const struct pm8xxx_adc_properties *adc_prop,
|
||||
const struct pm8xxx_adc_chan_properties *chan_prop,
|
||||
struct pm8xxx_adc_chan_result *chan_rslt)
|
||||
{ return -ENXIO; }
|
||||
static inline int32_t pm8xxx_adc_scale_pa_therm(int32_t adc_code,
|
||||
const struct pm8xxx_adc_properties *adc_prop,
|
||||
const struct pm8xxx_adc_chan_properties *chan_prop,
|
||||
struct pm8xxx_adc_chan_result *chan_rslt)
|
||||
{ return -ENXIO; }
|
||||
static inline int32_t pm8xxx_adc_scale_pmic_therm(int32_t adc_code,
|
||||
const struct pm8xxx_adc_properties *adc_prop,
|
||||
const struct pm8xxx_adc_chan_properties *chan_prop,
|
||||
struct pm8xxx_adc_chan_result *chan_rslt)
|
||||
{ return -ENXIO; }
|
||||
static inline int32_t pm8xxx_adc_scale_batt_id(int32_t adc_code,
|
||||
const struct pm8xxx_adc_properties *adc_prop,
|
||||
const struct pm8xxx_adc_chan_properties *chan_prop,
|
||||
struct pm8xxx_adc_chan_result *chan_rslt)
|
||||
{ return -ENXIO; }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* struct pm8xxx_adc_scale_fn - Scaling function prototype
|
||||
* @chan: Function pointer to one of the scaling functions
|
||||
* which takes the adc properties, channel properties,
|
||||
* and returns the physical result
|
||||
*/
|
||||
struct pm8xxx_adc_scale_fn {
|
||||
int32_t (*chan) (int32_t,
|
||||
const struct pm8xxx_adc_properties *,
|
||||
const struct pm8xxx_adc_chan_properties *,
|
||||
struct pm8xxx_adc_chan_result *);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pm8xxx_adc_amux - AMUX properties for individual channel
|
||||
* @name: Channel name
|
||||
* @channel_name: Channel in integer used from pm8xxx_adc_channels
|
||||
* @chan_path_prescaling: Channel scaling performed on the input signal
|
||||
* @adc_rsv: Input reference Voltage/GND selection to the ADC
|
||||
* @adc_decimation: Sampling rate desired for the channel
|
||||
* adc_scale_fn: Scaling function to convert to the data meaningful for
|
||||
* each individual channel whether it is voltage, current,
|
||||
* temperature, etc and compensates the channel properties
|
||||
*/
|
||||
struct pm8xxx_adc_amux {
|
||||
char *name;
|
||||
enum pm8xxx_adc_channels channel_name;
|
||||
enum pm8xxx_adc_channel_scaling_param chan_path_prescaling;
|
||||
enum pm8xxx_adc_amux_input_rsv adc_rsv;
|
||||
enum pm8xxx_adc_decimation_type adc_decimation;
|
||||
enum pm8xxx_adc_scale_fn_type adc_scale_fn;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pm8xxx_adc_arb_btm_param - PM8XXX ADC BTM parameters to set threshold
|
||||
* temperature for client notification
|
||||
* @low_thr_temp: low temperature threshold request for notification
|
||||
* @high_thr_temp: high temperature threshold request for notification
|
||||
* @low_thr_voltage: low temperature converted to voltage by arbiter driver
|
||||
* @high_thr_voltage: high temperature converted to voltage by arbiter driver
|
||||
* @interval: Interval period to check for temperature notification
|
||||
* @btm_warm_fn: Remote function call for warm threshold.
|
||||
* @btm_cool_fn: Remote function call for cold threshold.
|
||||
*
|
||||
* BTM client passes the parameters to be set for the
|
||||
* temperature threshold notifications. The client is
|
||||
* responsible for setting the new threshold
|
||||
* levels once the thresholds are reached
|
||||
*/
|
||||
struct pm8xxx_adc_arb_btm_param {
|
||||
int32_t low_thr_temp;
|
||||
int32_t high_thr_temp;
|
||||
uint64_t low_thr_voltage;
|
||||
uint64_t high_thr_voltage;
|
||||
int32_t interval;
|
||||
void (*btm_warm_fn) (bool);
|
||||
void (*btm_cool_fn) (bool);
|
||||
};
|
||||
|
||||
int32_t pm8xxx_adc_batt_scaler(struct pm8xxx_adc_arb_btm_param *,
|
||||
const struct pm8xxx_adc_properties *adc_prop,
|
||||
const struct pm8xxx_adc_chan_properties *chan_prop);
|
||||
/**
|
||||
* struct pm8xxx_adc_platform_data - PM8XXX ADC platform data
|
||||
* @adc_prop: ADC specific parameters, voltage and channel setup
|
||||
* @adc_channel: Channel properties of the ADC arbiter
|
||||
* @adc_num_board_channel: Number of channels added in the board file
|
||||
* @adc_mpp_base: PM8XXX MPP0 base passed from board file. This is used
|
||||
* to offset the PM8XXX MPP passed to configure the
|
||||
* the MPP to AMUX mapping.
|
||||
*/
|
||||
struct pm8xxx_adc_platform_data {
|
||||
struct pm8xxx_adc_properties *adc_prop;
|
||||
struct pm8xxx_adc_amux *adc_channel;
|
||||
uint32_t adc_num_board_channel;
|
||||
uint32_t adc_mpp_base;
|
||||
};
|
||||
|
||||
/* Public API */
|
||||
#if defined(CONFIG_SENSORS_PM8XXX_ADC) \
|
||||
|| defined(CONFIG_SENSORS_PM8XXX_ADC_MODULE)
|
||||
/**
|
||||
* pm8xxx_adc_read() - Performs ADC read on the channel.
|
||||
* @channel: Input channel to perform the ADC read.
|
||||
* @result: Structure pointer of type adc_chan_result
|
||||
* in which the ADC read results are stored.
|
||||
*/
|
||||
uint32_t pm8xxx_adc_read(enum pm8xxx_adc_channels channel,
|
||||
struct pm8xxx_adc_chan_result *result);
|
||||
/**
|
||||
* pm8xxx_adc_mpp_config_read() - Configure's the PM8XXX MPP
|
||||
* to AMUX6 and performs an ADC read.
|
||||
*
|
||||
* On PM8921 ADC the MPP needs to first be configured
|
||||
* as an analog input to the AMUX pre-mux channel before
|
||||
* issuing a read request. PM8921 MPP 8 is mapped to AMUX8
|
||||
* and is common between remote processor's.
|
||||
*
|
||||
* On PM8018 ADC the MPP is directly connected to the AMUX
|
||||
* pre-mux. Therefore clients of the PM8018 MPP do not need
|
||||
* to configure the MPP as an analog input to the pre-mux.
|
||||
* Clients can directly issue request on the pre-mux AMUX
|
||||
* channel to read the ADC on the MPP. Clients can directly
|
||||
* call the pm8xxx_adc_read().
|
||||
* @mpp_num PM8XXX MPP number to configure to AMUX6.
|
||||
* @channel: Input channel to perform the ADC read.
|
||||
* a) 'ADC_MPP_1_AMUX6' if the input voltage is less than 1.8V
|
||||
* b) 'ADC_MPP_2_AMUX6' if the input voltage is greater then 1.8V
|
||||
* the input voltage is pre-divided by 3 and passed to the ADC.
|
||||
* The appropriate scaling function needs to be selected to let
|
||||
* the driver know a post scaling is required before returning
|
||||
* the result.
|
||||
* @result: Structure pointer of type adc_chan_result
|
||||
* in which the ADC read results are stored.
|
||||
*/
|
||||
uint32_t pm8xxx_adc_mpp_config_read(uint32_t mpp_num,
|
||||
enum pm8xxx_adc_channels channel,
|
||||
struct pm8xxx_adc_chan_result *result);
|
||||
/**
|
||||
* pm8xxx_adc_btm_start() - Configure the BTM registers and start
|
||||
monitoring the BATT_THERM channel for
|
||||
threshold warm/cold temperature set
|
||||
by the Battery client. The btm_start
|
||||
api is to be used after calling the
|
||||
pm8xxx_btm_configure() api which sets
|
||||
the temperature thresholds, interval
|
||||
and functions to call when warm/cold
|
||||
events are triggered.
|
||||
* @param: none.
|
||||
*/
|
||||
uint32_t pm8xxx_adc_btm_start(void);
|
||||
|
||||
/**
|
||||
* pm8xxx_adc_btm_end() - Configures the BTM registers to stop
|
||||
* monitoring the BATT_THERM channel for
|
||||
* warm/cold events and disables the
|
||||
* interval timer.
|
||||
* @param: none.
|
||||
*/
|
||||
uint32_t pm8xxx_adc_btm_end(void);
|
||||
|
||||
/**
|
||||
* pm8xxx_adc_btm_configure() - Configures the BATT_THERM channel
|
||||
* parameters for warm/cold thresholds.
|
||||
* Sets the interval timer for perfoming
|
||||
* reading the temperature done by the HW.
|
||||
* @btm_param: Structure pointer of type adc_arb_btm_param *
|
||||
* which client provides for threshold warm/cold,
|
||||
* interval and functions to call when warm/cold
|
||||
* events are triggered.
|
||||
*/
|
||||
uint32_t pm8xxx_adc_btm_configure(struct pm8xxx_adc_arb_btm_param *);
|
||||
#else
|
||||
static inline uint32_t pm8xxx_adc_read(uint32_t channel,
|
||||
struct pm8xxx_adc_chan_result *result)
|
||||
{ return -ENXIO; }
|
||||
static inline uint32_t pm8xxx_adc_mpp_config_read(uint32_t mpp_num,
|
||||
enum pm8xxx_adc_channels channel,
|
||||
struct pm8xxx_adc_chan_result *result)
|
||||
{ return -ENXIO; }
|
||||
static inline uint32_t pm8xxx_adc_btm_start(void)
|
||||
{ return -ENXIO; }
|
||||
static inline uint32_t pm8xxx_adc_btm_end(void)
|
||||
{ return -ENXIO; }
|
||||
static inline uint32_t pm8xxx_adc_btm_configure(
|
||||
struct pm8xxx_adc_arb_btm_param *param)
|
||||
{ return -ENXIO; }
|
||||
#endif
|
||||
|
||||
#endif /* PM8XXX_ADC_H */
|
Loading…
Reference in a new issue