Lines Matching +full:avg +full:- +full:samples
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
21 #include <dt-bindings/iio/qcom,spmi-vadc.h>
23 #include "qcom-vadc-common.h"
76 * struct vadc_channel_prop - VADC channel property.
99 * struct vadc_priv - VADC private structure.
139 return regmap_bulk_read(vadc->regmap, vadc->base + offset, data, 1); in vadc_read()
144 return regmap_write(vadc->regmap, vadc->base + offset, data); in vadc_write()
203 dev_err(vadc->dev, in vadc_show_status()
222 ret = vadc_write(vadc, VADC_ADC_CH_SEL_CTL, prop->channel); in vadc_configure()
227 decimation = prop->decimation << VADC_ADC_DIG_DEC_RATIO_SEL_SHIFT; in vadc_configure()
233 ret = vadc_write(vadc, VADC_HW_SETTLE_DELAY, prop->hw_settle_time); in vadc_configure()
237 ret = vadc_write(vadc, VADC_FAST_AVG_CTL, prop->avg_samples); in vadc_configure()
241 if (prop->avg_samples) in vadc_configure()
271 return -ETIMEDOUT; in vadc_poll_wait_eoc()
278 ret = regmap_bulk_read(vadc->regmap, vadc->base + VADC_DATA, data, 2); in vadc_read_result()
292 for (i = 0; i < vadc->nchannels; i++) in vadc_get_channel()
293 if (vadc->chan_props[i].channel == num) in vadc_get_channel()
294 return &vadc->chan_props[i]; in vadc_get_channel()
296 dev_dbg(vadc->dev, "no such channel %02x\n", num); in vadc_get_channel()
307 mutex_lock(&vadc->lock); in vadc_do_conversion()
313 if (!vadc->poll_eoc) in vadc_do_conversion()
314 reinit_completion(&vadc->complete); in vadc_do_conversion()
324 timeout = BIT(prop->avg_samples) * VADC_CONV_TIME_MIN_US * 2; in vadc_do_conversion()
326 if (vadc->poll_eoc) { in vadc_do_conversion()
329 ret = wait_for_completion_timeout(&vadc->complete, timeout); in vadc_do_conversion()
331 ret = -ETIMEDOUT; in vadc_do_conversion()
346 dev_err(vadc->dev, "conversion failed\n"); in vadc_do_conversion()
348 mutex_unlock(&vadc->lock); in vadc_do_conversion()
358 vadc->graph[VADC_CALIB_RATIOMETRIC].dx = VADC_RATIOMETRIC_RANGE; in vadc_measure_ref_points()
359 vadc->graph[VADC_CALIB_ABSOLUTE].dx = VADC_ABSOLUTE_RANGE_UV; in vadc_measure_ref_points()
376 ret = -EINVAL; in vadc_measure_ref_points()
380 vadc->graph[VADC_CALIB_ABSOLUTE].dy = read_1 - read_2; in vadc_measure_ref_points()
381 vadc->graph[VADC_CALIB_ABSOLUTE].gnd = read_2; in vadc_measure_ref_points()
395 ret = -EINVAL; in vadc_measure_ref_points()
399 vadc->graph[VADC_CALIB_RATIOMETRIC].dy = read_1 - read_2; in vadc_measure_ref_points()
400 vadc->graph[VADC_CALIB_RATIOMETRIC].gnd = read_2; in vadc_measure_ref_points()
403 dev_err(vadc->dev, "measure reference points failed\n"); in vadc_measure_ref_points()
418 return -EINVAL; in vadc_prescaling_from_dt()
426 return -EINVAL; in vadc_hw_settle_time_from_dt()
439 return -EINVAL; in vadc_avg_samples_from_dt()
455 prop = &vadc->chan_props[chan->address]; in vadc_read_raw()
460 ret = qcom_vadc_scale(prop->scale_fn_type, in vadc_read_raw()
461 &vadc->graph[prop->calibration], in vadc_read_raw()
462 &vadc_prescale_ratios[prop->prescale], in vadc_read_raw()
463 (prop->calibration == VADC_CALIB_ABSOLUTE), in vadc_read_raw()
470 prop = &vadc->chan_props[chan->address]; in vadc_read_raw()
478 ret = -EINVAL; in vadc_read_raw()
491 for (i = 0; i < vadc->nchannels; i++) in vadc_of_xlate()
492 if (vadc->iio_chans[i].channel == iiospec->args[0]) in vadc_of_xlate()
495 return -EINVAL; in vadc_of_xlate()
655 const char *name = node->name; in vadc_get_dt_channel_data()
667 return -EINVAL; in vadc_get_dt_channel_data()
671 prop->channel = chan; in vadc_get_dt_channel_data()
681 prop->decimation = ret; in vadc_get_dt_channel_data()
683 prop->decimation = VADC_DEF_DECIMATION; in vadc_get_dt_channel_data()
686 ret = of_property_read_u32_array(node, "qcom,pre-scaling", varr, 2); in vadc_get_dt_channel_data()
690 dev_err(dev, "%02x invalid pre-scaling <%d %d>\n", in vadc_get_dt_channel_data()
694 prop->prescale = ret; in vadc_get_dt_channel_data()
696 prop->prescale = vadc_chans[prop->channel].prescale_index; in vadc_get_dt_channel_data()
699 ret = of_property_read_u32(node, "qcom,hw-settle-time", &value); in vadc_get_dt_channel_data()
703 dev_err(dev, "%02x invalid hw-settle-time %d us\n", in vadc_get_dt_channel_data()
707 prop->hw_settle_time = ret; in vadc_get_dt_channel_data()
709 prop->hw_settle_time = VADC_DEF_HW_SETTLE_TIME; in vadc_get_dt_channel_data()
712 ret = of_property_read_u32(node, "qcom,avg-samples", &value); in vadc_get_dt_channel_data()
716 dev_err(dev, "%02x invalid avg-samples %d\n", in vadc_get_dt_channel_data()
720 prop->avg_samples = ret; in vadc_get_dt_channel_data()
722 prop->avg_samples = VADC_DEF_AVG_SAMPLES; in vadc_get_dt_channel_data()
726 prop->calibration = VADC_CALIB_RATIOMETRIC; in vadc_get_dt_channel_data()
728 prop->calibration = VADC_CALIB_ABSOLUTE; in vadc_get_dt_channel_data()
744 vadc->nchannels = of_get_available_child_count(node); in vadc_get_dt_data()
745 if (!vadc->nchannels) in vadc_get_dt_data()
746 return -EINVAL; in vadc_get_dt_data()
748 vadc->iio_chans = devm_kcalloc(vadc->dev, vadc->nchannels, in vadc_get_dt_data()
749 sizeof(*vadc->iio_chans), GFP_KERNEL); in vadc_get_dt_data()
750 if (!vadc->iio_chans) in vadc_get_dt_data()
751 return -ENOMEM; in vadc_get_dt_data()
753 vadc->chan_props = devm_kcalloc(vadc->dev, vadc->nchannels, in vadc_get_dt_data()
754 sizeof(*vadc->chan_props), GFP_KERNEL); in vadc_get_dt_data()
755 if (!vadc->chan_props) in vadc_get_dt_data()
756 return -ENOMEM; in vadc_get_dt_data()
758 iio_chan = vadc->iio_chans; in vadc_get_dt_data()
761 ret = vadc_get_dt_channel_data(vadc->dev, &prop, child); in vadc_get_dt_data()
768 vadc->chan_props[index] = prop; in vadc_get_dt_data()
772 iio_chan->channel = prop.channel; in vadc_get_dt_data()
773 iio_chan->datasheet_name = vadc_chan->datasheet_name; in vadc_get_dt_data()
774 iio_chan->info_mask_separate = vadc_chan->info_mask; in vadc_get_dt_data()
775 iio_chan->type = vadc_chan->type; in vadc_get_dt_data()
776 iio_chan->indexed = 1; in vadc_get_dt_data()
777 iio_chan->address = index++; in vadc_get_dt_data()
784 dev_err(vadc->dev, "Please define 1.25V channel\n"); in vadc_get_dt_data()
785 return -ENODEV; in vadc_get_dt_data()
789 dev_err(vadc->dev, "Please define 0.625V channel\n"); in vadc_get_dt_data()
790 return -ENODEV; in vadc_get_dt_data()
794 dev_err(vadc->dev, "Please define VDD channel\n"); in vadc_get_dt_data()
795 return -ENODEV; in vadc_get_dt_data()
799 dev_err(vadc->dev, "Please define GND channel\n"); in vadc_get_dt_data()
800 return -ENODEV; in vadc_get_dt_data()
810 complete(&vadc->complete); in vadc_isr()
825 dev_err(vadc->dev, "%d is not ADC\n", val); in vadc_check_revision()
826 return -ENODEV; in vadc_check_revision()
834 dev_err(vadc->dev, "%d is not VADC\n", val); in vadc_check_revision()
835 return -ENODEV; in vadc_check_revision()
843 dev_err(vadc->dev, "revision %d not supported\n", val); in vadc_check_revision()
844 return -ENODEV; in vadc_check_revision()
852 struct device_node *node = pdev->dev.of_node; in vadc_probe()
853 struct device *dev = &pdev->dev; in vadc_probe()
860 regmap = dev_get_regmap(dev->parent, NULL); in vadc_probe()
862 return -ENODEV; in vadc_probe()
870 return -ENOMEM; in vadc_probe()
873 vadc->regmap = regmap; in vadc_probe()
874 vadc->dev = dev; in vadc_probe()
875 vadc->base = reg; in vadc_probe()
876 vadc->are_ref_measured = false; in vadc_probe()
877 init_completion(&vadc->complete); in vadc_probe()
878 mutex_init(&vadc->lock); in vadc_probe()
890 if (irq_eoc == -EPROBE_DEFER || irq_eoc == -EINVAL) in vadc_probe()
892 vadc->poll_eoc = true; in vadc_probe()
895 "spmi-vadc", vadc); in vadc_probe()
910 indio_dev->name = pdev->name; in vadc_probe()
911 indio_dev->modes = INDIO_DIRECT_MODE; in vadc_probe()
912 indio_dev->info = &vadc_info; in vadc_probe()
913 indio_dev->channels = vadc->iio_chans; in vadc_probe()
914 indio_dev->num_channels = vadc->nchannels; in vadc_probe()
920 { .compatible = "qcom,spmi-vadc" },
927 .name = "qcom-spmi-vadc",
934 MODULE_ALIAS("platform:qcom-spmi-vadc");
937 MODULE_AUTHOR("Stanimir Varbanov <svarbanov@mm-sol.com>");
938 MODULE_AUTHOR("Ivan T. Ivanov <iivanov@mm-sol.com>");