Merge "hwmon: qpnp-current: Fix parameter configuration for IADC"

This commit is contained in:
Linux Build Service Account
2014-08-12 09:16:32 -07:00
committed by Gerrit - the friendly Code Review server
3 changed files with 79 additions and 84 deletions
@@ -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>;
};
};
+40 -35
View File
@@ -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++;
}
+39 -8
View File
@@ -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);