Lines Matching +full:pre +full:- +full:scaling
1 // SPDX-License-Identifier: GPL-2.0
21 #include <dt-bindings/iio/qcom,spmi-vadc.h>
22 #include "qcom-vadc-common.h"
103 * struct adc5_channel_prop - ADC channel property.
109 * @prescale: channel scaling performed on the input signal.
114 * @scale_fn_type: Represents the scaling function to convert voltage
132 * struct adc5_chip - ADC private structure.
171 return regmap_bulk_read(adc->regmap, adc->base + offset, data, len); in adc5_read()
176 return regmap_bulk_write(adc->regmap, adc->base + offset, data, len); in adc5_write()
181 return regmap_update_bits(adc->regmap, adc->base + offset, mask, val); in adc5_masked_write()
186 unsigned int pre; in adc5_prescaling_from_dt() local
188 for (pre = 0; pre < ARRAY_SIZE(adc5_prescale_ratios); pre++) in adc5_prescaling_from_dt()
189 if (adc5_prescale_ratios[pre].num == num && in adc5_prescaling_from_dt()
190 adc5_prescale_ratios[pre].den == den) in adc5_prescaling_from_dt()
193 if (pre == ARRAY_SIZE(adc5_prescale_ratios)) in adc5_prescaling_from_dt()
194 return -EINVAL; in adc5_prescaling_from_dt()
196 return pre; in adc5_prescaling_from_dt()
209 return -EINVAL; in adc5_hw_settle_time_from_dt()
215 return -EINVAL; in adc5_avg_samples_from_dt()
230 return -EINVAL; in adc5_decimation_from_dt()
249 dev_err(adc->dev, "Invalid data:0x%x\n", *data); in adc5_read_voltage_data()
250 return -EINVAL; in adc5_read_voltage_data()
253 dev_dbg(adc->dev, "voltage raw code:0x%x\n", *data); in adc5_read_voltage_data()
277 return -ETIMEDOUT; in adc5_poll_wait_eoc()
285 *data |= (prop->cal_val << ADC5_USR_DIG_PARAM_CAL_VAL_SHIFT); in adc5_update_dig_param()
289 *data |= (prop->cal_method << ADC5_USR_DIG_PARAM_CAL_SEL_SHIFT); in adc5_update_dig_param()
293 *data |= (prop->decimation << ADC5_USR_DIG_PARAM_DEC_RATIO_SEL_SHIFT); in adc5_update_dig_param()
312 buf[1] |= prop->avg_samples; in adc5_configure()
315 buf[2] = prop->channel; in adc5_configure()
319 buf[3] |= prop->hw_settle_time; in adc5_configure()
327 if (!adc->poll_eoc) in adc5_configure()
328 reinit_completion(&adc->complete); in adc5_configure()
339 ret = adc5_masked_write(adc, ADC_APP_SID, ADC_APP_SID_MASK, prop->sid); in adc7_configure()
352 buf[1] |= prop->avg_samples; in adc7_configure()
355 buf[2] = prop->channel; in adc7_configure()
359 buf[3] |= prop->hw_settle_time; in adc7_configure()
364 if (!adc->poll_eoc) in adc7_configure()
365 reinit_completion(&adc->complete); in adc7_configure()
381 mutex_lock(&adc->lock); in adc5_do_conversion()
385 dev_err(adc->dev, "ADC configure failed with %d\n", ret); in adc5_do_conversion()
389 if (adc->poll_eoc) { in adc5_do_conversion()
392 dev_err(adc->dev, "EOC bit not set\n"); in adc5_do_conversion()
396 ret = wait_for_completion_timeout(&adc->complete, in adc5_do_conversion()
399 dev_dbg(adc->dev, "Did not get completion timeout.\n"); in adc5_do_conversion()
402 dev_err(adc->dev, "EOC bit not set\n"); in adc5_do_conversion()
410 mutex_unlock(&adc->lock); in adc5_do_conversion()
423 mutex_lock(&adc->lock); in adc7_do_conversion()
427 dev_err(adc->dev, "ADC configure failed with %d\n", ret); in adc7_do_conversion()
432 wait_for_completion_timeout(&adc->complete, ADC7_CONV_TIMEOUT); in adc7_do_conversion()
439 dev_err(adc->dev, "Unexpected conversion fault\n"); in adc7_do_conversion()
440 ret = -EIO; in adc7_do_conversion()
447 mutex_unlock(&adc->lock); in adc7_do_conversion()
461 complete(&adc->complete); in adc5_isr()
472 for (i = 0; i < adc->nchannels; i++) in adc5_of_xlate()
473 if (adc->chan_props[i].channel == iiospec->args[0]) in adc5_of_xlate()
476 return -EINVAL; in adc5_of_xlate()
485 for (i = 0; i < adc->nchannels; i++) { in adc7_of_xlate()
486 v_channel = (adc->chan_props[i].sid << ADC_CHANNEL_OFFSET) | in adc7_of_xlate()
487 adc->chan_props[i].channel; in adc7_of_xlate()
488 if (v_channel == iiospec->args[0]) in adc7_of_xlate()
492 return -EINVAL; in adc7_of_xlate()
504 prop = &adc->chan_props[chan->address]; in adc_read_raw_common()
513 ret = qcom_adc5_hw_scale(prop->scale_fn_type, in adc_read_raw_common()
514 &adc5_prescale_ratios[prop->prescale], in adc_read_raw_common()
515 adc->data, in adc_read_raw_common()
522 return -EINVAL; in adc_read_raw_common()
679 const char *name = node->name, *channel_name; in adc5_get_dt_channel_data()
683 struct device *dev = adc->dev; in adc5_get_dt_channel_data()
695 if (adc->data->info == &adc7_info) { in adc5_get_dt_channel_data()
701 !data->adc_chans[chan].datasheet_name) { in adc5_get_dt_channel_data()
703 return -EINVAL; in adc5_get_dt_channel_data()
707 prop->channel = chan; in adc5_get_dt_channel_data()
708 prop->sid = sid; in adc5_get_dt_channel_data()
711 "label", NULL) ? : node->name; in adc5_get_dt_channel_data()
714 return -EINVAL; in adc5_get_dt_channel_data()
716 prop->datasheet_name = channel_name; in adc5_get_dt_channel_data()
720 ret = adc5_decimation_from_dt(value, data->decimation); in adc5_get_dt_channel_data()
726 prop->decimation = ret; in adc5_get_dt_channel_data()
728 prop->decimation = ADC5_DECIMATION_DEFAULT; in adc5_get_dt_channel_data()
731 ret = of_property_read_u32_array(node, "qcom,pre-scaling", varr, 2); in adc5_get_dt_channel_data()
735 dev_err(dev, "%02x invalid pre-scaling <%d %d>\n", in adc5_get_dt_channel_data()
739 prop->prescale = ret; in adc5_get_dt_channel_data()
741 prop->prescale = in adc5_get_dt_channel_data()
742 adc->data->adc_chans[prop->channel].prescale_index; in adc5_get_dt_channel_data()
745 ret = of_property_read_u32(node, "qcom,hw-settle-time", &value); in adc5_get_dt_channel_data()
761 adc->data->info == &adc7_info) in adc5_get_dt_channel_data()
763 data->hw_settle_2); in adc5_get_dt_channel_data()
766 data->hw_settle_1); in adc5_get_dt_channel_data()
769 dev_err(dev, "%02x invalid hw-settle-time %d us\n", in adc5_get_dt_channel_data()
773 prop->hw_settle_time = ret; in adc5_get_dt_channel_data()
775 prop->hw_settle_time = VADC_DEF_HW_SETTLE_TIME; in adc5_get_dt_channel_data()
778 ret = of_property_read_u32(node, "qcom,avg-samples", &value); in adc5_get_dt_channel_data()
782 dev_err(dev, "%02x invalid avg-samples %d\n", in adc5_get_dt_channel_data()
786 prop->avg_samples = ret; in adc5_get_dt_channel_data()
788 prop->avg_samples = VADC_DEF_AVG_SAMPLES; in adc5_get_dt_channel_data()
792 prop->cal_method = ADC5_RATIOMETRIC_CAL; in adc5_get_dt_channel_data()
794 prop->cal_method = ADC5_ABSOLUTE_CAL; in adc5_get_dt_channel_data()
800 prop->cal_val = ADC5_TIMER_CAL; in adc5_get_dt_channel_data()
851 .compatible = "qcom,spmi-adc5",
855 .compatible = "qcom,spmi-adc7",
859 .compatible = "qcom,spmi-adc-rev2",
877 adc->nchannels = of_get_available_child_count(node); in adc5_get_dt_data()
878 if (!adc->nchannels) in adc5_get_dt_data()
879 return -EINVAL; in adc5_get_dt_data()
881 adc->iio_chans = devm_kcalloc(adc->dev, adc->nchannels, in adc5_get_dt_data()
882 sizeof(*adc->iio_chans), GFP_KERNEL); in adc5_get_dt_data()
883 if (!adc->iio_chans) in adc5_get_dt_data()
884 return -ENOMEM; in adc5_get_dt_data()
886 adc->chan_props = devm_kcalloc(adc->dev, adc->nchannels, in adc5_get_dt_data()
887 sizeof(*adc->chan_props), GFP_KERNEL); in adc5_get_dt_data()
888 if (!adc->chan_props) in adc5_get_dt_data()
889 return -ENOMEM; in adc5_get_dt_data()
891 chan_props = adc->chan_props; in adc5_get_dt_data()
892 iio_chan = adc->iio_chans; in adc5_get_dt_data()
895 data = id->data; in adc5_get_dt_data()
898 adc->data = data; in adc5_get_dt_data()
908 data->adc_chans[prop.channel].scale_fn_type; in adc5_get_dt_data()
910 adc_chan = &data->adc_chans[prop.channel]; in adc5_get_dt_data()
912 iio_chan->channel = prop.channel; in adc5_get_dt_data()
913 iio_chan->datasheet_name = prop.datasheet_name; in adc5_get_dt_data()
914 iio_chan->extend_name = prop.datasheet_name; in adc5_get_dt_data()
915 iio_chan->info_mask_separate = adc_chan->info_mask; in adc5_get_dt_data()
916 iio_chan->type = adc_chan->type; in adc5_get_dt_data()
917 iio_chan->address = index; in adc5_get_dt_data()
928 struct device_node *node = pdev->dev.of_node; in adc5_probe()
929 struct device *dev = &pdev->dev; in adc5_probe()
936 regmap = dev_get_regmap(dev->parent, NULL); in adc5_probe()
938 return -ENODEV; in adc5_probe()
946 return -ENOMEM; in adc5_probe()
949 adc->regmap = regmap; in adc5_probe()
950 adc->dev = dev; in adc5_probe()
951 adc->base = reg; in adc5_probe()
953 init_completion(&adc->complete); in adc5_probe()
954 mutex_init(&adc->lock); in adc5_probe()
964 if (irq_eoc == -EPROBE_DEFER || irq_eoc == -EINVAL) in adc5_probe()
966 adc->poll_eoc = true; in adc5_probe()
969 "pm-adc5", adc); in adc5_probe()
974 indio_dev->name = pdev->name; in adc5_probe()
975 indio_dev->modes = INDIO_DIRECT_MODE; in adc5_probe()
976 indio_dev->info = adc->data->info; in adc5_probe()
977 indio_dev->channels = adc->iio_chans; in adc5_probe()
978 indio_dev->num_channels = adc->nchannels; in adc5_probe()
985 .name = "qcom-spmi-adc5",
992 MODULE_ALIAS("platform:qcom-spmi-adc5");