mirror of
https://github.com/LineageOS/android_kernel_samsung_msm8226.git
synced 2026-09-29 00:00:25 +02:00
Merge "hwmon: qpnp-current: Fix parameter configuration for IADC"
This commit is contained in:
committed by
Gerrit - the friendly Code Review server
commit
47457d583a
@@ -58,43 +58,6 @@ Required properties:
|
||||
1 : 1K
|
||||
2 : 2K
|
||||
3 : 4K
|
||||
- qcom,pre-div-channel-scaling : Pre-div used for the channel before the signal
|
||||
is being measured.
|
||||
- qcom,calibration-type : Calibration point values vary with temperature.
|
||||
For improved accuracy fresh gain and offset point values
|
||||
can be used for calibration. Reading fresh values for ever
|
||||
read affects the reading time. Application can use the historic
|
||||
values used from the trim register values.
|
||||
Select from the following strings.
|
||||
"absolute" : Uses TRIM gain and offset values for calibration.
|
||||
"ratiometric" : Calculate the gain and offset calibration value when an ADC
|
||||
request is issued.
|
||||
- qcom,scale-function : Scaling fuction used to convert raw ADC code to units specific to
|
||||
a given channel.
|
||||
Select from the following unsigned int.
|
||||
0 : Default scaling to convert raw adc code to voltage.
|
||||
1 : Conversion to temperature based on btm parameters.
|
||||
2 : Returns result in milli degree's Centigrade.
|
||||
3 : Returns current across 0.1 ohm resistor.
|
||||
4 : Returns XO thermistor voltage in degree's Centigrade.
|
||||
- qcom,hw-settle-time : Settling period for the channel before ADC read.
|
||||
Select from the following unsigned int.
|
||||
0 : 0us
|
||||
1 : 100us
|
||||
2 : 200us
|
||||
3 : 300us
|
||||
4 : 400us
|
||||
5 : 500us
|
||||
6 : 600us
|
||||
7 : 700us
|
||||
8 : 800us
|
||||
9 : 900us
|
||||
0xa : 1ms
|
||||
0xb : 2ms
|
||||
0xc : 4ms
|
||||
0xd : 6ms
|
||||
0xe : 8ms
|
||||
0xf : 10ms
|
||||
- qcom,fast-avg-setup : Average number of samples to be used for measurement. Fast averaging
|
||||
provides the option to obtain a single measurement from the ADC that
|
||||
is an average of multiple samples. The value selected is 2^(value)
|
||||
@@ -130,10 +93,6 @@ Example:
|
||||
label = "rsense";
|
||||
reg = <0>;
|
||||
qcom,decimation = <0>;
|
||||
qcom,pre-div-channel-scaling = <20>;
|
||||
qcom,calibration-type = "fresh";
|
||||
qcom,scale-function = <0>;
|
||||
qcom,hw-settle-time = <0>;
|
||||
qcom,fast-avg-setup = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1128,7 +1128,7 @@ int32_t qpnp_adc_get_devicetree_data(struct spmi_device *spmi,
|
||||
|
||||
for_each_child_of_node(node, child) {
|
||||
int channel_num, scaling, post_scaling, hw_settle_time;
|
||||
int fast_avg_setup, calib_type, rc;
|
||||
int fast_avg_setup, calib_type = 0, rc;
|
||||
const char *calibration_param, *channel_name;
|
||||
|
||||
channel_name = of_get_property(child,
|
||||
@@ -1149,23 +1149,40 @@ int32_t qpnp_adc_get_devicetree_data(struct spmi_device *spmi,
|
||||
pr_err("Invalid channel decimation property\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
rc = of_property_read_u32(child,
|
||||
"qcom,pre-div-channel-scaling", &scaling);
|
||||
if (rc) {
|
||||
pr_err("Invalid channel scaling property\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
rc = of_property_read_u32(child,
|
||||
"qcom,scale-function", &post_scaling);
|
||||
if (rc) {
|
||||
pr_err("Invalid channel post scaling property\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
rc = of_property_read_u32(child,
|
||||
if (!of_device_is_compatible(node, "qcom,qpnp-iadc")) {
|
||||
rc = of_property_read_u32(child,
|
||||
"qcom,hw-settle-time", &hw_settle_time);
|
||||
if (rc) {
|
||||
pr_err("Invalid channel hw settle time property\n");
|
||||
return -EINVAL;
|
||||
if (rc) {
|
||||
pr_err("Invalid channel hw settle time property\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
rc = of_property_read_u32(child,
|
||||
"qcom,pre-div-channel-scaling", &scaling);
|
||||
if (rc) {
|
||||
pr_err("Invalid channel scaling property\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
rc = of_property_read_u32(child,
|
||||
"qcom,scale-function", &post_scaling);
|
||||
if (rc) {
|
||||
pr_err("Invalid channel post scaling property\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
rc = of_property_read_string(child,
|
||||
"qcom,calibration-type", &calibration_param);
|
||||
if (rc) {
|
||||
pr_err("Invalid calibration type\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!strcmp(calibration_param, "absolute"))
|
||||
calib_type = CALIB_ABSOLUTE;
|
||||
else if (!strcmp(calibration_param, "ratiometric"))
|
||||
calib_type = CALIB_RATIOMETRIC;
|
||||
else {
|
||||
pr_err("%s: Invalid calibration property\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
rc = of_property_read_u32(child,
|
||||
"qcom,fast-avg-setup", &fast_avg_setup);
|
||||
@@ -1173,29 +1190,17 @@ int32_t qpnp_adc_get_devicetree_data(struct spmi_device *spmi,
|
||||
pr_err("Invalid channel fast average setup\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
rc = of_property_read_string(child, "qcom,calibration-type",
|
||||
&calibration_param);
|
||||
if (rc) {
|
||||
pr_err("Invalid calibration type\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!strncmp(calibration_param, "absolute", 8))
|
||||
calib_type = CALIB_ABSOLUTE;
|
||||
else if (!strncmp(calibration_param, "ratiometric", 11))
|
||||
calib_type = CALIB_RATIOMETRIC;
|
||||
else {
|
||||
pr_err("%s: Invalid calibration property\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
/* Individual channel properties */
|
||||
adc_channel_list[i].name = (char *)channel_name;
|
||||
adc_channel_list[i].channel_num = channel_num;
|
||||
adc_channel_list[i].chan_path_prescaling = scaling;
|
||||
adc_channel_list[i].adc_decimation = decimation;
|
||||
adc_channel_list[i].adc_scale_fn = post_scaling;
|
||||
adc_channel_list[i].hw_settle_time = hw_settle_time;
|
||||
adc_channel_list[i].fast_avg_setup = fast_avg_setup;
|
||||
adc_channel_list[i].calib_type = calib_type;
|
||||
if (!of_device_is_compatible(node, "qcom,qpnp-iadc")) {
|
||||
adc_channel_list[i].chan_path_prescaling = scaling;
|
||||
adc_channel_list[i].adc_scale_fn = post_scaling;
|
||||
adc_channel_list[i].hw_settle_time = hw_settle_time;
|
||||
adc_channel_list[i].calib_type = calib_type;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,6 @@
|
||||
#define QPNP_ADC_DEC_RATIO_SEL_MASK 0xc
|
||||
#define QPNP_ADC_DIG_DEC_RATIO_SEL_SHIFT 2
|
||||
|
||||
#define QPNP_HW_SETTLE_DELAY 0x51
|
||||
#define QPNP_CONV_REQ 0x52
|
||||
#define QPNP_CONV_REQ_SET BIT(7)
|
||||
#define QPNP_CONV_SEQ_CTL 0x54
|
||||
@@ -163,6 +162,7 @@ struct qpnp_iadc_chip {
|
||||
bool iadc_poll_eoc;
|
||||
u16 batt_id_trim_cnst_rds;
|
||||
int rds_trim_default_type;
|
||||
int max_channels_available;
|
||||
bool rds_trim_default_check;
|
||||
int32_t rsense_workaround_value;
|
||||
struct sensor_device_attribute sens_attr[0];
|
||||
@@ -802,13 +802,6 @@ static int32_t qpnp_iadc_configure(struct qpnp_iadc_chip *iadc,
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = qpnp_iadc_write_reg(iadc, QPNP_HW_SETTLE_DELAY,
|
||||
iadc->adc->amux_prop->hw_settle_time);
|
||||
if (rc < 0) {
|
||||
pr_err("qpnp adc configure error for hw settling time setup\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = qpnp_iadc_write_reg(iadc, QPNP_FAST_AVG_CTL,
|
||||
iadc->adc->amux_prop->fast_avg_setup);
|
||||
if (rc < 0) {
|
||||
@@ -927,6 +920,9 @@ int32_t qpnp_iadc_calibrate_for_trim(struct qpnp_iadc_chip *iadc,
|
||||
pm_stay_awake(iadc->dev);
|
||||
}
|
||||
|
||||
iadc->adc->amux_prop->decimation = DECIMATION_TYPE1;
|
||||
iadc->adc->amux_prop->fast_avg_setup = ADC_FAST_AVG_SAMPLE_1;
|
||||
|
||||
rc = qpnp_iadc_configure(iadc, GAIN_CALIBRATION_17P857MV,
|
||||
&raw_data, mode_sel);
|
||||
if (rc < 0) {
|
||||
@@ -1170,6 +1166,7 @@ int32_t qpnp_iadc_read(struct qpnp_iadc_chip *iadc,
|
||||
int32_t rsense_u_ohms = 0;
|
||||
int64_t result_current;
|
||||
uint16_t raw_data;
|
||||
int dt_index = 0;
|
||||
|
||||
if (qpnp_iadc_is_valid(iadc) < 0)
|
||||
return -EPROBE_DEFER;
|
||||
@@ -1187,6 +1184,22 @@ int32_t qpnp_iadc_read(struct qpnp_iadc_chip *iadc,
|
||||
|
||||
mutex_lock(&iadc->adc->adc_lock);
|
||||
|
||||
while (((enum qpnp_iadc_channels)
|
||||
iadc->adc->adc_channels[dt_index].channel_num
|
||||
!= channel) && (dt_index < iadc->max_channels_available))
|
||||
dt_index++;
|
||||
|
||||
if (dt_index >= iadc->max_channels_available) {
|
||||
pr_err("not a valid IADC channel\n");
|
||||
rc = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
iadc->adc->amux_prop->decimation =
|
||||
iadc->adc->adc_channels[dt_index].adc_decimation;
|
||||
iadc->adc->amux_prop->fast_avg_setup =
|
||||
iadc->adc->adc_channels[dt_index].fast_avg_setup;
|
||||
|
||||
if (iadc->iadc_poll_eoc) {
|
||||
pr_debug("acquiring iadc eoc wakelock\n");
|
||||
pm_stay_awake(iadc->dev);
|
||||
@@ -1289,6 +1302,7 @@ int32_t qpnp_iadc_vadc_sync_read(struct qpnp_iadc_chip *iadc,
|
||||
enum qpnp_vadc_channels v_channel, struct qpnp_vadc_result *v_result)
|
||||
{
|
||||
int rc = 0, mode_sel = 0, num = 0, rsense_n_ohms = 0, sign = 0;
|
||||
int dt_index = 0;
|
||||
uint16_t raw_data;
|
||||
int32_t rsense_u_ohms = 0;
|
||||
int64_t result_current;
|
||||
@@ -1316,6 +1330,22 @@ int32_t qpnp_iadc_vadc_sync_read(struct qpnp_iadc_chip *iadc,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
while (((enum qpnp_iadc_channels)
|
||||
iadc->adc->adc_channels[dt_index].channel_num
|
||||
!= i_channel) && (dt_index < iadc->max_channels_available))
|
||||
dt_index++;
|
||||
|
||||
if (dt_index >= iadc->max_channels_available) {
|
||||
pr_err("not a valid IADC channel\n");
|
||||
rc = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
iadc->adc->amux_prop->decimation =
|
||||
iadc->adc->adc_channels[dt_index].adc_decimation;
|
||||
iadc->adc->amux_prop->fast_avg_setup =
|
||||
iadc->adc->adc_channels[dt_index].fast_avg_setup;
|
||||
|
||||
rc = qpnp_iadc_configure(iadc, i_channel, &raw_data, mode_sel);
|
||||
if (rc < 0) {
|
||||
pr_err("qpnp adc result read failed with %d\n", rc);
|
||||
@@ -1529,6 +1559,7 @@ static int __devinit qpnp_iadc_probe(struct spmi_device *spmi)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
iadc->max_channels_available = count_adc_channel_list;
|
||||
INIT_WORK(&iadc->trigger_completion_work, qpnp_iadc_trigger_completion);
|
||||
INIT_DELAYED_WORK(&iadc->iadc_work, qpnp_iadc_work);
|
||||
rc = qpnp_iadc_comp_info(iadc);
|
||||
|
||||
Reference in New Issue
Block a user