mirror of
https://github.com/torvalds/linux.git
synced 2026-07-31 03:27:03 +02:00
Merge "iio: qcom-spmi-adc5: add support to read current channels"
This commit is contained in:
commit
0a2dfab4a7
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/bitops.h>
|
||||
|
|
@ -75,9 +75,10 @@
|
|||
* samples and measurements queued across different VADC peripherals.
|
||||
* Set the timeout to a max of 100ms.
|
||||
*/
|
||||
#define ADC5_CONV_TIME_MIN_US 263
|
||||
#define ADC5_CONV_TIME_MAX_US 264
|
||||
#define ADC5_CONV_TIME_RETRY 400
|
||||
#define ADC5_POLL_DELAY_MIN_US 10000
|
||||
#define ADC5_POLL_DELAY_MAX_US 10001
|
||||
#define ADC5_CONV_TIME_RETRY_POLL 40
|
||||
#define ADC5_CONV_TIME_RETRY 30
|
||||
#define ADC5_CONV_TIMEOUT msecs_to_jiffies(100)
|
||||
|
||||
/* Digital version >= 5.3 supports hw_settle_2 */
|
||||
|
|
@ -87,7 +88,7 @@
|
|||
/* For PMIC7 */
|
||||
#define ADC_APP_SID 0x40
|
||||
#define ADC_APP_SID_MASK GENMASK(3, 0)
|
||||
#define ADC7_CONV_TIMEOUT msecs_to_jiffies(10)
|
||||
#define ADC7_CONV_TIMEOUT_MS 501
|
||||
|
||||
enum adc5_cal_method {
|
||||
ADC5_NO_CAL = 0,
|
||||
|
|
@ -195,12 +196,17 @@ static int adc5_read_voltage_data(struct adc5_chip *adc, u16 *data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int adc5_poll_wait_eoc(struct adc5_chip *adc)
|
||||
static int adc5_poll_wait_eoc(struct adc5_chip *adc, bool poll_only)
|
||||
{
|
||||
unsigned int count, retry = ADC5_CONV_TIME_RETRY;
|
||||
u8 status1;
|
||||
int ret;
|
||||
|
||||
if (poll_only)
|
||||
retry = ADC5_CONV_TIME_RETRY_POLL;
|
||||
else
|
||||
retry = ADC5_CONV_TIME_RETRY;
|
||||
|
||||
for (count = 0; count < retry; count++) {
|
||||
ret = adc5_read(adc, ADC5_USR_STATUS1, &status1,
|
||||
sizeof(status1));
|
||||
|
|
@ -211,7 +217,7 @@ static int adc5_poll_wait_eoc(struct adc5_chip *adc)
|
|||
if (status1 == ADC5_USR_STATUS1_EOC)
|
||||
return 0;
|
||||
|
||||
usleep_range(ADC5_CONV_TIME_MIN_US, ADC5_CONV_TIME_MAX_US);
|
||||
usleep_range(ADC5_POLL_DELAY_MIN_US, ADC5_POLL_DELAY_MAX_US);
|
||||
}
|
||||
|
||||
return -ETIMEDOUT;
|
||||
|
|
@ -327,7 +333,7 @@ static int adc5_do_conversion(struct adc5_chip *adc,
|
|||
}
|
||||
|
||||
if (adc->poll_eoc) {
|
||||
ret = adc5_poll_wait_eoc(adc);
|
||||
ret = adc5_poll_wait_eoc(adc, true);
|
||||
if (ret) {
|
||||
dev_err(adc->dev, "EOC bit not set\n");
|
||||
goto unlock;
|
||||
|
|
@ -337,7 +343,7 @@ static int adc5_do_conversion(struct adc5_chip *adc,
|
|||
ADC5_CONV_TIMEOUT);
|
||||
if (!ret) {
|
||||
dev_dbg(adc->dev, "Did not get completion timeout.\n");
|
||||
ret = adc5_poll_wait_eoc(adc);
|
||||
ret = adc5_poll_wait_eoc(adc, false);
|
||||
if (ret) {
|
||||
dev_err(adc->dev, "EOC bit not set\n");
|
||||
goto unlock;
|
||||
|
|
@ -359,6 +365,8 @@ static int adc7_do_conversion(struct adc5_chip *adc,
|
|||
{
|
||||
int ret;
|
||||
u8 status;
|
||||
unsigned long rc;
|
||||
unsigned int time_pending_ms;
|
||||
|
||||
mutex_lock(&adc->lock);
|
||||
|
||||
|
|
@ -369,14 +377,44 @@ static int adc7_do_conversion(struct adc5_chip *adc,
|
|||
}
|
||||
|
||||
/* No support for polling mode at present */
|
||||
wait_for_completion_timeout(&adc->complete, ADC7_CONV_TIMEOUT);
|
||||
rc = wait_for_completion_timeout(&adc->complete,
|
||||
msecs_to_jiffies(ADC7_CONV_TIMEOUT_MS));
|
||||
if (!rc) {
|
||||
dev_err(adc->dev, "Reading ADC channel %s timed out\n",
|
||||
prop->datasheet_name);
|
||||
ret = -ETIMEDOUT;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
/*
|
||||
* As per the hardware documentation, EOC should happen within 15 ms
|
||||
* in a good case where there could be multiple conversion requests
|
||||
* going through PMIC HW arbiter for reading ADC channels. However, if
|
||||
* for some reason, one of the conversion request fails and times out,
|
||||
* worst possible delay can be 500 ms. Hence print a warning when we
|
||||
* see EOC completion happened more than 15 ms.
|
||||
*/
|
||||
time_pending_ms = jiffies_to_msecs(rc);
|
||||
if (time_pending_ms < ADC7_CONV_TIMEOUT_MS &&
|
||||
(ADC7_CONV_TIMEOUT_MS - time_pending_ms) > 15)
|
||||
dev_warn(adc->dev, "ADC channel %s EOC took %u ms\n",
|
||||
prop->datasheet_name,
|
||||
ADC7_CONV_TIMEOUT_MS - time_pending_ms);
|
||||
|
||||
ret = adc5_read(adc, ADC5_USR_STATUS1, &status, 1);
|
||||
if (ret)
|
||||
goto unlock;
|
||||
|
||||
if (status & ADC5_USR_STATUS1_CONV_FAULT) {
|
||||
dev_err(adc->dev, "Unexpected conversion fault\n");
|
||||
dev_err(adc->dev, "ADC channel %s unexpected conversion fault\n",
|
||||
prop->datasheet_name);
|
||||
ret = -EIO;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (!(status & ADC5_USR_STATUS1_EOC)) {
|
||||
dev_err(adc->dev, "ADC channel %s EOC bit not set, status=%#x\n",
|
||||
prop->datasheet_name, status);
|
||||
ret = -EIO;
|
||||
goto unlock;
|
||||
}
|
||||
|
|
@ -517,6 +555,11 @@ struct adc5_channels {
|
|||
BIT(IIO_CHAN_INFO_PROCESSED), \
|
||||
_pre, _scale) \
|
||||
|
||||
#define ADC5_CHAN_CUR(_dname, _pre, _scale) \
|
||||
ADC5_CHAN(_dname, IIO_CURRENT, \
|
||||
BIT(IIO_CHAN_INFO_PROCESSED), \
|
||||
_pre, _scale) \
|
||||
|
||||
static const struct adc5_channels adc5_chans_pmic[ADC5_MAX_CHANNEL] = {
|
||||
[ADC5_REF_GND] = ADC5_CHAN_VOLT("ref_gnd", 0,
|
||||
SCALE_HW_CALIB_DEFAULT)
|
||||
|
|
@ -541,14 +584,32 @@ static const struct adc5_channels adc5_chans_pmic[ADC5_MAX_CHANNEL] = {
|
|||
SCALE_HW_CALIB_DEFAULT)
|
||||
[ADC5_XO_THERM_100K_PU] = ADC5_CHAN_TEMP("xo_therm", 0,
|
||||
SCALE_HW_CALIB_XOTHERM)
|
||||
[ADC5_BAT_THERM_100K_PU] = ADC5_CHAN_TEMP("bat_therm_100k_pu", 0,
|
||||
SCALE_HW_CALIB_BATT_THERM_100K)
|
||||
[ADC5_BAT_THERM_30K_PU] = ADC5_CHAN_TEMP("bat_therm_30k_pu", 0,
|
||||
SCALE_HW_CALIB_BATT_THERM_30K)
|
||||
[ADC5_BAT_THERM_400K_PU] = ADC5_CHAN_TEMP("bat_therm_400k_pu", 0,
|
||||
SCALE_HW_CALIB_BATT_THERM_400K)
|
||||
[ADC5_BAT_ID_100K_PU] = ADC5_CHAN_TEMP("bat_id", 0,
|
||||
SCALE_HW_CALIB_DEFAULT)
|
||||
[ADC5_AMUX_THM1_100K_PU] = ADC5_CHAN_TEMP("amux_thm1_100k_pu", 0,
|
||||
SCALE_HW_CALIB_THERM_100K_PULLUP)
|
||||
[ADC5_AMUX_THM2_100K_PU] = ADC5_CHAN_TEMP("amux_thm2_100k_pu", 0,
|
||||
SCALE_HW_CALIB_THERM_100K_PULLUP)
|
||||
[ADC5_AMUX_THM3_100K_PU] = ADC5_CHAN_TEMP("amux_thm3_100k_pu", 0,
|
||||
SCALE_HW_CALIB_THERM_100K_PULLUP)
|
||||
[ADC5_AMUX_THM4_100K_PU] = ADC5_CHAN_TEMP("amux_thm4_100k_pu", 0,
|
||||
SCALE_HW_CALIB_THERM_100K_PULLUP)
|
||||
[ADC5_AMUX_THM2] = ADC5_CHAN_TEMP("amux_thm2", 0,
|
||||
SCALE_HW_CALIB_PM5_SMB_TEMP)
|
||||
[ADC5_GPIO1_100K_PU] = ADC5_CHAN_TEMP("gpio1_100k_pu", 0,
|
||||
SCALE_HW_CALIB_THERM_100K_PULLUP)
|
||||
[ADC5_GPIO2_100K_PU] = ADC5_CHAN_TEMP("gpio2_100k_pu", 0,
|
||||
SCALE_HW_CALIB_THERM_100K_PULLUP)
|
||||
[ADC5_GPIO3_100K_PU] = ADC5_CHAN_TEMP("gpio3_100k_pu", 0,
|
||||
SCALE_HW_CALIB_THERM_100K_PULLUP)
|
||||
[ADC5_GPIO4_100K_PU] = ADC5_CHAN_TEMP("gpio4_100k_pu", 0,
|
||||
SCALE_HW_CALIB_THERM_100K_PULLUP)
|
||||
};
|
||||
|
||||
static const struct adc5_channels adc7_chans_pmic[ADC5_MAX_CHANNEL] = {
|
||||
|
|
@ -560,6 +621,18 @@ static const struct adc5_channels adc7_chans_pmic[ADC5_MAX_CHANNEL] = {
|
|||
SCALE_HW_CALIB_DEFAULT)
|
||||
[ADC7_VBAT_SNS] = ADC5_CHAN_VOLT("vbat_sns", 3,
|
||||
SCALE_HW_CALIB_DEFAULT)
|
||||
[ADC7_AMUX_THM3] = ADC5_CHAN_TEMP("smb_temp", 0,
|
||||
SCALE_HW_CALIB_PM7_SMB_TEMP)
|
||||
[ADC7_CHG_TEMP] = ADC5_CHAN_TEMP("chg_temp", 0,
|
||||
SCALE_HW_CALIB_PM7_CHG_TEMP)
|
||||
[ADC7_IIN_FB] = ADC5_CHAN_CUR("iin_fb", 9,
|
||||
SCALE_HW_CALIB_CUR)
|
||||
[ADC7_ICHG_SMB] = ADC5_CHAN_CUR("ichg_smb", 10,
|
||||
SCALE_HW_CALIB_CUR)
|
||||
[ADC7_IIN_SMB] = ADC5_CHAN_CUR("iin_smb", 11,
|
||||
SCALE_HW_CALIB_CUR)
|
||||
[ADC7_ICHG_FB] = ADC5_CHAN_CUR("ichg_fb", 12,
|
||||
SCALE_HW_CALIB_CUR_RAW)
|
||||
[ADC7_DIE_TEMP] = ADC5_CHAN_TEMP("die_temp", 0,
|
||||
SCALE_HW_CALIB_PMIC_THERM_PM7)
|
||||
[ADC7_AMUX_THM1_100K_PU] = ADC5_CHAN_TEMP("amux_thm1_pu2", 0,
|
||||
|
|
|
|||
|
|
@ -100,6 +100,237 @@ static const struct vadc_map_pt adcmap_100k_104ef_104fb_1875_vref[] = {
|
|||
{ 46, 125000 },
|
||||
};
|
||||
|
||||
/*
|
||||
* Voltage to temperature table for 100k pull up for bat_therm with
|
||||
* Alium.
|
||||
*/
|
||||
static const struct vadc_map_pt adcmap_batt_therm_100k[] = {
|
||||
{1840, -400},
|
||||
{1835, -380},
|
||||
{1828, -360},
|
||||
{1821, -340},
|
||||
{1813, -320},
|
||||
{1803, -300},
|
||||
{1793, -280},
|
||||
{1781, -260},
|
||||
{1768, -240},
|
||||
{1753, -220},
|
||||
{1737, -200},
|
||||
{1719, -180},
|
||||
{1700, -160},
|
||||
{1679, -140},
|
||||
{1655, -120},
|
||||
{1630, -100},
|
||||
{1603, -80},
|
||||
{1574, -60},
|
||||
{1543, -40},
|
||||
{1510, -20},
|
||||
{1475, 0},
|
||||
{1438, 20},
|
||||
{1400, 40},
|
||||
{1360, 60},
|
||||
{1318, 80},
|
||||
{1276, 100},
|
||||
{1232, 120},
|
||||
{1187, 140},
|
||||
{1142, 160},
|
||||
{1097, 180},
|
||||
{1051, 200},
|
||||
{1005, 220},
|
||||
{960, 240},
|
||||
{915, 260},
|
||||
{871, 280},
|
||||
{828, 300},
|
||||
{786, 320},
|
||||
{745, 340},
|
||||
{705, 360},
|
||||
{666, 380},
|
||||
{629, 400},
|
||||
{594, 420},
|
||||
{560, 440},
|
||||
{527, 460},
|
||||
{497, 480},
|
||||
{467, 500},
|
||||
{439, 520},
|
||||
{413, 540},
|
||||
{388, 560},
|
||||
{365, 580},
|
||||
{343, 600},
|
||||
{322, 620},
|
||||
{302, 640},
|
||||
{284, 660},
|
||||
{267, 680},
|
||||
{251, 700},
|
||||
{235, 720},
|
||||
{221, 740},
|
||||
{208, 760},
|
||||
{195, 780},
|
||||
{184, 800},
|
||||
{173, 820},
|
||||
{163, 840},
|
||||
{153, 860},
|
||||
{144, 880},
|
||||
{136, 900},
|
||||
{128, 920},
|
||||
{120, 940},
|
||||
{114, 960},
|
||||
{107, 980}
|
||||
};
|
||||
|
||||
/*
|
||||
* Voltage to temperature table for 30k pull up for bat_therm with
|
||||
* Alium.
|
||||
*/
|
||||
static const struct vadc_map_pt adcmap_batt_therm_30k[] = {
|
||||
{1864, -400},
|
||||
{1863, -380},
|
||||
{1861, -360},
|
||||
{1858, -340},
|
||||
{1856, -320},
|
||||
{1853, -300},
|
||||
{1850, -280},
|
||||
{1846, -260},
|
||||
{1842, -240},
|
||||
{1837, -220},
|
||||
{1831, -200},
|
||||
{1825, -180},
|
||||
{1819, -160},
|
||||
{1811, -140},
|
||||
{1803, -120},
|
||||
{1794, -100},
|
||||
{1784, -80},
|
||||
{1773, -60},
|
||||
{1761, -40},
|
||||
{1748, -20},
|
||||
{1734, 0},
|
||||
{1718, 20},
|
||||
{1702, 40},
|
||||
{1684, 60},
|
||||
{1664, 80},
|
||||
{1643, 100},
|
||||
{1621, 120},
|
||||
{1597, 140},
|
||||
{1572, 160},
|
||||
{1546, 180},
|
||||
{1518, 200},
|
||||
{1489, 220},
|
||||
{1458, 240},
|
||||
{1426, 260},
|
||||
{1393, 280},
|
||||
{1359, 300},
|
||||
{1324, 320},
|
||||
{1288, 340},
|
||||
{1252, 360},
|
||||
{1214, 380},
|
||||
{1176, 400},
|
||||
{1138, 420},
|
||||
{1100, 440},
|
||||
{1061, 460},
|
||||
{1023, 480},
|
||||
{985, 500},
|
||||
{947, 520},
|
||||
{910, 540},
|
||||
{873, 560},
|
||||
{836, 580},
|
||||
{801, 600},
|
||||
{766, 620},
|
||||
{732, 640},
|
||||
{699, 660},
|
||||
{668, 680},
|
||||
{637, 700},
|
||||
{607, 720},
|
||||
{578, 740},
|
||||
{550, 760},
|
||||
{524, 780},
|
||||
{498, 800},
|
||||
{474, 820},
|
||||
{451, 840},
|
||||
{428, 860},
|
||||
{407, 880},
|
||||
{387, 900},
|
||||
{367, 920},
|
||||
{349, 940},
|
||||
{332, 960},
|
||||
{315, 980}
|
||||
};
|
||||
|
||||
/*
|
||||
* Voltage to temperature table for 400k pull up for bat_therm with
|
||||
* Alium.
|
||||
*/
|
||||
static const struct vadc_map_pt adcmap_batt_therm_400k[] = {
|
||||
{1744, -400},
|
||||
{1724, -380},
|
||||
{1701, -360},
|
||||
{1676, -340},
|
||||
{1648, -320},
|
||||
{1618, -300},
|
||||
{1584, -280},
|
||||
{1548, -260},
|
||||
{1509, -240},
|
||||
{1468, -220},
|
||||
{1423, -200},
|
||||
{1377, -180},
|
||||
{1328, -160},
|
||||
{1277, -140},
|
||||
{1225, -120},
|
||||
{1171, -100},
|
||||
{1117, -80},
|
||||
{1062, -60},
|
||||
{1007, -40},
|
||||
{953, -20},
|
||||
{899, 0},
|
||||
{847, 20},
|
||||
{795, 40},
|
||||
{745, 60},
|
||||
{697, 80},
|
||||
{651, 100},
|
||||
{607, 120},
|
||||
{565, 140},
|
||||
{526, 160},
|
||||
{488, 180},
|
||||
{453, 200},
|
||||
{420, 220},
|
||||
{390, 240},
|
||||
{361, 260},
|
||||
{334, 280},
|
||||
{309, 300},
|
||||
{286, 320},
|
||||
{265, 340},
|
||||
{245, 360},
|
||||
{227, 380},
|
||||
{210, 400},
|
||||
{195, 420},
|
||||
{180, 440},
|
||||
{167, 460},
|
||||
{155, 480},
|
||||
{144, 500},
|
||||
{133, 520},
|
||||
{124, 540},
|
||||
{115, 560},
|
||||
{107, 580},
|
||||
{99, 600},
|
||||
{92, 620},
|
||||
{86, 640},
|
||||
{80, 660},
|
||||
{75, 680},
|
||||
{70, 700},
|
||||
{65, 720},
|
||||
{61, 740},
|
||||
{57, 760},
|
||||
{53, 780},
|
||||
{50, 800},
|
||||
{46, 820},
|
||||
{43, 840},
|
||||
{41, 860},
|
||||
{38, 880},
|
||||
{36, 900},
|
||||
{34, 920},
|
||||
{32, 940},
|
||||
{30, 960},
|
||||
{28, 980}
|
||||
};
|
||||
|
||||
static const struct vadc_map_pt adcmap7_die_temp[] = {
|
||||
{ 857300, 160000 },
|
||||
{ 820100, 140000 },
|
||||
|
|
@ -299,16 +530,42 @@ static const struct u32_fract adc5_prescale_ratios[] = {
|
|||
{ .numerator = 10, .denominator = 81 },
|
||||
{ .numerator = 1, .denominator = 10 },
|
||||
{ .numerator = 1, .denominator = 16 },
|
||||
/* Prescale ratios for current channels below */
|
||||
{ .numerator = 32, .denominator = 100 }, /* IIN_FB */
|
||||
{ .numerator = 14, .denominator = 100 }, /* ICHG_SMB */
|
||||
{ .numerator = 28, .denominator = 100 }, /* IIN_SMB */
|
||||
{ .numerator = 1000, .denominator = 305185 }, /* ICHG_FB */
|
||||
{ .numerator = 1000, .denominator = 610370 }, /* ICHG_FB_2X */
|
||||
};
|
||||
|
||||
static int qcom_vadc_scale_hw_calib_volt(
|
||||
const struct u32_fract *prescale,
|
||||
const struct adc5_data *data,
|
||||
u16 adc_code, int *result_uv);
|
||||
static int qcom_vadc_scale_hw_calib_current(
|
||||
const struct u32_fract *prescale,
|
||||
const struct adc5_data *data,
|
||||
u16 adc_code, int *result_ua);
|
||||
static int qcom_vadc_scale_hw_calib_current_raw(
|
||||
const struct u32_fract *prescale,
|
||||
const struct adc5_data *data,
|
||||
u16 adc_code, int *result_ua);
|
||||
static int qcom_vadc_scale_hw_calib_therm(
|
||||
const struct u32_fract *prescale,
|
||||
const struct adc5_data *data,
|
||||
u16 adc_code, int *result_mdec);
|
||||
static int qcom_vadc_scale_hw_calib_batt_therm_100(
|
||||
const struct u32_fract *prescale,
|
||||
const struct adc5_data *data,
|
||||
u16 adc_code, int *result_mdec);
|
||||
static int qcom_vadc_scale_hw_calib_batt_therm_30(
|
||||
const struct u32_fract *prescale,
|
||||
const struct adc5_data *data,
|
||||
u16 adc_code, int *result_mdec);
|
||||
static int qcom_vadc_scale_hw_calib_batt_therm_400(
|
||||
const struct u32_fract *prescale,
|
||||
const struct adc5_data *data,
|
||||
u16 adc_code, int *result_mdec);
|
||||
static int qcom_vadc7_scale_hw_calib_therm(
|
||||
const struct u32_fract *prescale,
|
||||
const struct adc5_data *data,
|
||||
|
|
@ -317,10 +574,22 @@ static int qcom_vadc_scale_hw_smb_temp(
|
|||
const struct u32_fract *prescale,
|
||||
const struct adc5_data *data,
|
||||
u16 adc_code, int *result_mdec);
|
||||
static int qcom_vadc_scale_hw_pm7_smb_temp(
|
||||
const struct u32_fract *prescale,
|
||||
const struct adc5_data *data,
|
||||
u16 adc_code, int *result_mdec);
|
||||
static int qcom_vadc_scale_hw_smb1398_temp(
|
||||
const struct u32_fract *prescale,
|
||||
const struct adc5_data *data,
|
||||
u16 adc_code, int *result_mdec);
|
||||
static int qcom_vadc_scale_hw_chg5_temp(
|
||||
const struct u32_fract *prescale,
|
||||
const struct adc5_data *data,
|
||||
u16 adc_code, int *result_mdec);
|
||||
static int qcom_vadc_scale_hw_pm7_chg_temp(
|
||||
const struct u32_fract *prescale,
|
||||
const struct adc5_data *data,
|
||||
u16 adc_code, int *result_mdec);
|
||||
static int qcom_vadc_scale_hw_calib_die_temp(
|
||||
const struct u32_fract *prescale,
|
||||
const struct adc5_data *data,
|
||||
|
|
@ -332,7 +601,15 @@ static int qcom_vadc7_scale_hw_calib_die_temp(
|
|||
|
||||
static struct qcom_adc5_scale_type scale_adc5_fn[] = {
|
||||
[SCALE_HW_CALIB_DEFAULT] = {qcom_vadc_scale_hw_calib_volt},
|
||||
[SCALE_HW_CALIB_CUR] = {qcom_vadc_scale_hw_calib_current},
|
||||
[SCALE_HW_CALIB_CUR_RAW] = {qcom_vadc_scale_hw_calib_current_raw},
|
||||
[SCALE_HW_CALIB_THERM_100K_PULLUP] = {qcom_vadc_scale_hw_calib_therm},
|
||||
[SCALE_HW_CALIB_BATT_THERM_100K] = {
|
||||
qcom_vadc_scale_hw_calib_batt_therm_100},
|
||||
[SCALE_HW_CALIB_BATT_THERM_30K] = {
|
||||
qcom_vadc_scale_hw_calib_batt_therm_30},
|
||||
[SCALE_HW_CALIB_BATT_THERM_400K] = {
|
||||
qcom_vadc_scale_hw_calib_batt_therm_400},
|
||||
[SCALE_HW_CALIB_XOTHERM] = {qcom_vadc_scale_hw_calib_therm},
|
||||
[SCALE_HW_CALIB_THERM_100K_PU_PM7] = {
|
||||
qcom_vadc7_scale_hw_calib_therm},
|
||||
|
|
@ -341,6 +618,9 @@ static struct qcom_adc5_scale_type scale_adc5_fn[] = {
|
|||
qcom_vadc7_scale_hw_calib_die_temp},
|
||||
[SCALE_HW_CALIB_PM5_CHG_TEMP] = {qcom_vadc_scale_hw_chg5_temp},
|
||||
[SCALE_HW_CALIB_PM5_SMB_TEMP] = {qcom_vadc_scale_hw_smb_temp},
|
||||
[SCALE_HW_CALIB_PM5_SMB1398_TEMP] = {qcom_vadc_scale_hw_smb1398_temp},
|
||||
[SCALE_HW_CALIB_PM7_SMB_TEMP] = {qcom_vadc_scale_hw_pm7_smb_temp},
|
||||
[SCALE_HW_CALIB_PM7_CHG_TEMP] = {qcom_vadc_scale_hw_pm7_chg_temp},
|
||||
};
|
||||
|
||||
static int qcom_vadc_map_voltage_temp(const struct vadc_map_pt *pts,
|
||||
|
|
@ -556,6 +836,45 @@ static int qcom_vadc7_scale_hw_calib_therm(
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int qcom_vadc_scale_hw_calib_current_raw(
|
||||
const struct u32_fract *prescale,
|
||||
const struct adc5_data *data,
|
||||
u16 adc_code, int *result_ua)
|
||||
{
|
||||
s64 temp;
|
||||
|
||||
if (!prescale->numerator)
|
||||
return -EINVAL;
|
||||
|
||||
temp = div_s64((s64)(s16)adc_code * prescale->denominator,
|
||||
prescale->numerator);
|
||||
*result_ua = (int) temp;
|
||||
pr_debug("raw adc_code: %#x result_ua: %d\n", adc_code, *result_ua);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qcom_vadc_scale_hw_calib_current(
|
||||
const struct u32_fract *prescale,
|
||||
const struct adc5_data *data,
|
||||
u16 adc_code, int *result_ua)
|
||||
{
|
||||
u32 adc_vdd_ref_mv = 1875;
|
||||
s64 voltage;
|
||||
|
||||
if (!prescale->numerator)
|
||||
return -EINVAL;
|
||||
|
||||
/* (ADC code * vref_vadc (1.875V)) / full_scale_code */
|
||||
voltage = (s64)(s16) adc_code * adc_vdd_ref_mv * 1000;
|
||||
voltage = div_s64(voltage, data->full_scale_code_volt);
|
||||
voltage = div_s64(voltage * prescale->denominator, prescale->numerator);
|
||||
*result_ua = (int) voltage;
|
||||
pr_debug("adc_code: %#x result_ua: %d\n", adc_code, *result_ua);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qcom_vadc_scale_hw_calib_volt(
|
||||
const struct u32_fract *prescale,
|
||||
const struct adc5_data *data,
|
||||
|
|
@ -583,6 +902,54 @@ static int qcom_vadc_scale_hw_calib_therm(
|
|||
voltage, result_mdec);
|
||||
}
|
||||
|
||||
static int qcom_vadc_scale_hw_calib_batt_therm_100(
|
||||
const struct u32_fract *prescale,
|
||||
const struct adc5_data *data,
|
||||
u16 adc_code, int *result_mdec)
|
||||
{
|
||||
int voltage;
|
||||
|
||||
voltage = qcom_vadc_scale_code_voltage_factor(adc_code,
|
||||
prescale, data, 1000);
|
||||
|
||||
/* Map voltage to temperature from look-up table */
|
||||
return qcom_vadc_map_voltage_temp(adcmap_batt_therm_100k,
|
||||
ARRAY_SIZE(adcmap_batt_therm_100k),
|
||||
voltage, result_mdec);
|
||||
}
|
||||
|
||||
static int qcom_vadc_scale_hw_calib_batt_therm_30(
|
||||
const struct u32_fract *prescale,
|
||||
const struct adc5_data *data,
|
||||
u16 adc_code, int *result_mdec)
|
||||
{
|
||||
int voltage;
|
||||
|
||||
voltage = qcom_vadc_scale_code_voltage_factor(adc_code,
|
||||
prescale, data, 1000);
|
||||
|
||||
/* Map voltage to temperature from look-up table */
|
||||
return qcom_vadc_map_voltage_temp(adcmap_batt_therm_30k,
|
||||
ARRAY_SIZE(adcmap_batt_therm_30k),
|
||||
voltage, result_mdec);
|
||||
}
|
||||
|
||||
static int qcom_vadc_scale_hw_calib_batt_therm_400(
|
||||
const struct u32_fract *prescale,
|
||||
const struct adc5_data *data,
|
||||
u16 adc_code, int *result_mdec)
|
||||
{
|
||||
int voltage;
|
||||
|
||||
voltage = qcom_vadc_scale_code_voltage_factor(adc_code,
|
||||
prescale, data, 1000);
|
||||
|
||||
/* Map voltage to temperature from look-up table */
|
||||
return qcom_vadc_map_voltage_temp(adcmap_batt_therm_400k,
|
||||
ARRAY_SIZE(adcmap_batt_therm_400k),
|
||||
voltage, result_mdec);
|
||||
}
|
||||
|
||||
static int qcom_vadc_scale_hw_calib_die_temp(
|
||||
const struct u32_fract *prescale,
|
||||
const struct adc5_data *data,
|
||||
|
|
@ -610,6 +977,47 @@ static int qcom_vadc7_scale_hw_calib_die_temp(
|
|||
voltage, result_mdec);
|
||||
}
|
||||
|
||||
static int qcom_vadc_scale_hw_pm7_chg_temp(
|
||||
const struct u32_fract *prescale,
|
||||
const struct adc5_data *data,
|
||||
u16 adc_code, int *result_mdec)
|
||||
{
|
||||
s64 temp;
|
||||
int result_uv;
|
||||
|
||||
result_uv = qcom_vadc_scale_code_voltage_factor(adc_code,
|
||||
prescale, data, 1);
|
||||
|
||||
/* T(C) = Vadc/0.0033 – 277.12 */
|
||||
temp = div_s64((30303LL * result_uv) - (27712 * 1000000LL), 100000);
|
||||
pr_debug("adc_code: %u result_uv: %d temp: %lld\n", adc_code, result_uv,
|
||||
temp);
|
||||
*result_mdec = temp > 0 ? temp : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qcom_vadc_scale_hw_pm7_smb_temp(
|
||||
const struct u32_fract *prescale,
|
||||
const struct adc5_data *data,
|
||||
u16 adc_code, int *result_mdec)
|
||||
{
|
||||
s64 temp;
|
||||
int result_uv;
|
||||
|
||||
result_uv = qcom_vadc_scale_code_voltage_factor(adc_code,
|
||||
prescale, data, 1);
|
||||
|
||||
/* T(C) = 25 + (25*Vadc - 24.885) / 0.0894 */
|
||||
temp = div_s64(((25000LL * result_uv) - (24885 * 1000000LL)) * 10000,
|
||||
894 * 1000000) + 25000;
|
||||
pr_debug("adc_code: %#x result_uv: %d temp: %lld\n", adc_code,
|
||||
result_uv, temp);
|
||||
*result_mdec = temp > 0 ? temp : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qcom_vadc_scale_hw_smb_temp(
|
||||
const struct u32_fract *prescale,
|
||||
const struct adc5_data *data,
|
||||
|
|
@ -622,6 +1030,35 @@ static int qcom_vadc_scale_hw_smb_temp(
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int qcom_vadc_scale_hw_smb1398_temp(
|
||||
const struct u32_fract *prescale,
|
||||
const struct adc5_data *data,
|
||||
u16 adc_code, int *result_mdec)
|
||||
{
|
||||
s64 voltage = 0, adc_vdd_ref_mv = 1875;
|
||||
u64 temp;
|
||||
|
||||
if (adc_code > VADC5_MAX_CODE)
|
||||
adc_code = 0;
|
||||
|
||||
/* (ADC code * vref_vadc (1.875V)) / full_scale_code */
|
||||
voltage = (s64) adc_code * adc_vdd_ref_mv * 1000;
|
||||
voltage = div64_s64(voltage, data->full_scale_code_volt);
|
||||
if (voltage > 0) {
|
||||
temp = voltage * prescale->denominator;
|
||||
temp *= 100;
|
||||
do_div(temp, prescale->numerator * PMIC5_SMB1398_TEMP_SCALE_FACTOR);
|
||||
voltage = temp;
|
||||
} else {
|
||||
voltage = 0;
|
||||
}
|
||||
|
||||
voltage = voltage - PMIC5_SMB1398_TEMP_CONSTANT;
|
||||
*result_mdec = voltage;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qcom_vadc_scale_hw_chg5_temp(
|
||||
const struct u32_fract *prescale,
|
||||
const struct adc5_data *data,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2012-2014,2018,2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2012-2014,2018-2020 The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_QCOM_SPMI_VADC_H
|
||||
|
|
@ -245,6 +245,9 @@
|
|||
#define ADC7_CC1_ID 0x13
|
||||
#define ADC7_VREF_BAT_THERM 0x15
|
||||
#define ADC7_IIN_FB 0x17
|
||||
#define ADC7_ICHG_SMB 0x18
|
||||
#define ADC7_IIN_SMB 0x19
|
||||
#define ADC7_ICHG_FB 0xa1
|
||||
|
||||
/* 30k pull-up1 */
|
||||
#define ADC7_AMUX_THM1_30K_PU 0x24
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@
|
|||
#define PMIC5_CHG_TEMP_SCALE_FACTOR 377500
|
||||
#define PMIC5_SMB_TEMP_CONSTANT 419400
|
||||
#define PMIC5_SMB_TEMP_SCALE_FACTOR 356
|
||||
#define PMIC5_SMB1398_TEMP_CONSTANT 268235
|
||||
#define PMIC5_SMB1398_TEMP_SCALE_FACTOR 340
|
||||
|
||||
#define PMI_CHG_SCALE_1 -138890
|
||||
#define PMI_CHG_SCALE_2 391750000000LL
|
||||
|
|
@ -99,12 +101,31 @@ struct vadc_linear_graph {
|
|||
* lookup table for PMIC7. The hardware applies offset/slope to adc code.
|
||||
* SCALE_HW_CALIB_PMIC_THERM: Returns result in milli degree's Centigrade.
|
||||
* The hardware applies offset/slope to adc code.
|
||||
* SCALE_HW_CALIB_PMIC_THERM: Returns result in milli degree's Centigrade.
|
||||
* SCALE_HW_CALIB_PMIC_THERM_PM7: Returns result in milli degree's Centigrade.
|
||||
* The hardware applies offset/slope to adc code. This is for PMIC7.
|
||||
* SCALE_HW_CALIB_PM5_CHG_TEMP: Returns result in millidegrees for PMIC5
|
||||
* charger temperature.
|
||||
* SCALE_HW_CALIB_PM5_SMB_TEMP: Returns result in millidegrees for PMIC5
|
||||
* SMB1390 temperature.
|
||||
* SCALE_HW_CALIB_BATT_THERM_100K: Returns battery thermistor voltage in
|
||||
* decidegC using 100k pullup. The hardware applies offset/slope to adc
|
||||
* code.
|
||||
* SCALE_HW_CALIB_BATT_THERM_30K: Returns battery thermistor voltage in
|
||||
* decidegC using 30k pullup. The hardware applies offset/slope to adc
|
||||
* code.
|
||||
* SCALE_HW_CALIB_BATT_THERM_400K: Returns battery thermistor voltage in
|
||||
* decidegC using 400k pullup. The hardware applies offset/slope to adc
|
||||
* code.
|
||||
* SCALE_HW_CALIB_PM5_SMB1398_TEMP: Returns result in millidegrees for PMIC5
|
||||
* SMB1398 temperature.
|
||||
* SCALE_HW_CALIB_PM7_SMB_TEMP: Returns result in millidegrees for PMIC7
|
||||
* SMB139x temperature.
|
||||
* SCALE_HW_CALIB_PM7_CHG_TEMP: Returns result in millidegrees for PMIC7
|
||||
* charger temperature.
|
||||
* SCALE_HW_CALIB_CUR: Returns result in microamperes for PMIC7 channels that
|
||||
* use voltage scaling.
|
||||
* SCALE_HW_CALIB_CUR_RAW: Returns result in microamperes for PMIC7 channels
|
||||
* that use raw ADC code.
|
||||
*/
|
||||
enum vadc_scale_fn_type {
|
||||
SCALE_DEFAULT = 0,
|
||||
|
|
@ -120,6 +141,14 @@ enum vadc_scale_fn_type {
|
|||
SCALE_HW_CALIB_PMIC_THERM_PM7,
|
||||
SCALE_HW_CALIB_PM5_CHG_TEMP,
|
||||
SCALE_HW_CALIB_PM5_SMB_TEMP,
|
||||
SCALE_HW_CALIB_BATT_THERM_100K,
|
||||
SCALE_HW_CALIB_BATT_THERM_30K,
|
||||
SCALE_HW_CALIB_BATT_THERM_400K,
|
||||
SCALE_HW_CALIB_PM5_SMB1398_TEMP,
|
||||
SCALE_HW_CALIB_PM7_SMB_TEMP,
|
||||
SCALE_HW_CALIB_PM7_CHG_TEMP,
|
||||
SCALE_HW_CALIB_CUR,
|
||||
SCALE_HW_CALIB_CUR_RAW,
|
||||
SCALE_HW_CALIB_INVALID,
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user