Lines Matching +full:pre +full:- +full:calibration

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
10 #include <linux/iio/adc/qcom-vadc-common.h>
23 #include <dt-bindings/iio/qcom,spmi-vadc.h>
76 * struct vadc_channel_prop - VADC channel property.
78 * @calibration: calibration type.
91 enum vadc_calibration calibration; member
101 * struct vadc_priv - VADC private structure.
111 * @graph: store parameters for calibration.
141 return regmap_bulk_read(vadc->regmap, vadc->base + offset, data, 1); in vadc_read()
146 return regmap_write(vadc->regmap, vadc->base + offset, data); in vadc_write()
205 dev_err(vadc->dev, in vadc_show_status()
224 ret = vadc_write(vadc, VADC_ADC_CH_SEL_CTL, prop->channel); in vadc_configure()
229 decimation = prop->decimation << VADC_ADC_DIG_DEC_RATIO_SEL_SHIFT; in vadc_configure()
235 ret = vadc_write(vadc, VADC_HW_SETTLE_DELAY, prop->hw_settle_time); in vadc_configure()
239 ret = vadc_write(vadc, VADC_FAST_AVG_CTL, prop->avg_samples); in vadc_configure()
243 if (prop->avg_samples) in vadc_configure()
273 return -ETIMEDOUT; in vadc_poll_wait_eoc()
280 ret = regmap_bulk_read(vadc->regmap, vadc->base + VADC_DATA, data, 2); in vadc_read_result()
294 for (i = 0; i < vadc->nchannels; i++) in vadc_get_channel()
295 if (vadc->chan_props[i].channel == num) in vadc_get_channel()
296 return &vadc->chan_props[i]; in vadc_get_channel()
298 dev_dbg(vadc->dev, "no such channel %02x\n", num); in vadc_get_channel()
309 mutex_lock(&vadc->lock); in vadc_do_conversion()
315 if (!vadc->poll_eoc) in vadc_do_conversion()
316 reinit_completion(&vadc->complete); in vadc_do_conversion()
326 timeout = BIT(prop->avg_samples) * VADC_CONV_TIME_MIN_US * 2; in vadc_do_conversion()
328 if (vadc->poll_eoc) { in vadc_do_conversion()
331 ret = wait_for_completion_timeout(&vadc->complete, timeout); in vadc_do_conversion()
333 ret = -ETIMEDOUT; in vadc_do_conversion()
348 dev_err(vadc->dev, "conversion failed\n"); in vadc_do_conversion()
350 mutex_unlock(&vadc->lock); in vadc_do_conversion()
360 vadc->graph[VADC_CALIB_RATIOMETRIC].dx = VADC_RATIOMETRIC_RANGE; in vadc_measure_ref_points()
361 vadc->graph[VADC_CALIB_ABSOLUTE].dx = VADC_ABSOLUTE_RANGE_UV; in vadc_measure_ref_points()
378 ret = -EINVAL; in vadc_measure_ref_points()
382 vadc->graph[VADC_CALIB_ABSOLUTE].dy = read_1 - read_2; in vadc_measure_ref_points()
383 vadc->graph[VADC_CALIB_ABSOLUTE].gnd = read_2; in vadc_measure_ref_points()
385 /* Ratiometric calibration */ in vadc_measure_ref_points()
397 ret = -EINVAL; in vadc_measure_ref_points()
401 vadc->graph[VADC_CALIB_RATIOMETRIC].dy = read_1 - read_2; in vadc_measure_ref_points()
402 vadc->graph[VADC_CALIB_RATIOMETRIC].gnd = read_2; in vadc_measure_ref_points()
405 dev_err(vadc->dev, "measure reference points failed\n"); in vadc_measure_ref_points()
412 unsigned int pre; in vadc_prescaling_from_dt() local
414 for (pre = 0; pre < ARRAY_SIZE(vadc_prescale_ratios); pre++) in vadc_prescaling_from_dt()
415 if (vadc_prescale_ratios[pre].numerator == numerator && in vadc_prescaling_from_dt()
416 vadc_prescale_ratios[pre].denominator == denominator) in vadc_prescaling_from_dt()
419 if (pre == ARRAY_SIZE(vadc_prescale_ratios)) in vadc_prescaling_from_dt()
420 return -EINVAL; in vadc_prescaling_from_dt()
422 return pre; in vadc_prescaling_from_dt()
428 return -EINVAL; in vadc_hw_settle_time_from_dt()
441 return -EINVAL; in vadc_avg_samples_from_dt()
457 prop = &vadc->chan_props[chan->address]; in vadc_read_raw()
462 ret = qcom_vadc_scale(prop->scale_fn_type, in vadc_read_raw()
463 &vadc->graph[prop->calibration], in vadc_read_raw()
464 &vadc_prescale_ratios[prop->prescale], in vadc_read_raw()
465 (prop->calibration == VADC_CALIB_ABSOLUTE), in vadc_read_raw()
472 prop = &vadc->chan_props[chan->address]; in vadc_read_raw()
480 ret = -EINVAL; in vadc_read_raw()
493 for (i = 0; i < vadc->nchannels; i++) in vadc_fwnode_xlate()
494 if (vadc->iio_chans[i].channel == iiospec->args[0]) in vadc_fwnode_xlate()
497 return -EINVAL; in vadc_fwnode_xlate()
504 const char *name = vadc->chan_props[chan->address].channel_name; in vadc_read_label()
679 return -EINVAL; in vadc_get_fw_channel_data()
685 prop->channel_name = label; in vadc_get_fw_channel_data()
688 prop->channel = chan; in vadc_get_fw_channel_data()
698 prop->decimation = ret; in vadc_get_fw_channel_data()
700 prop->decimation = VADC_DEF_DECIMATION; in vadc_get_fw_channel_data()
703 ret = fwnode_property_read_u32_array(fwnode, "qcom,pre-scaling", varr, 2); in vadc_get_fw_channel_data()
707 dev_err(dev, "%02x invalid pre-scaling <%d %d>\n", in vadc_get_fw_channel_data()
711 prop->prescale = ret; in vadc_get_fw_channel_data()
713 prop->prescale = vadc_chans[prop->channel].prescale_index; in vadc_get_fw_channel_data()
716 ret = fwnode_property_read_u32(fwnode, "qcom,hw-settle-time", &value); in vadc_get_fw_channel_data()
720 dev_err(dev, "%02x invalid hw-settle-time %d us\n", in vadc_get_fw_channel_data()
724 prop->hw_settle_time = ret; in vadc_get_fw_channel_data()
726 prop->hw_settle_time = VADC_DEF_HW_SETTLE_TIME; in vadc_get_fw_channel_data()
729 ret = fwnode_property_read_u32(fwnode, "qcom,avg-samples", &value); in vadc_get_fw_channel_data()
733 dev_err(dev, "%02x invalid avg-samples %d\n", in vadc_get_fw_channel_data()
737 prop->avg_samples = ret; in vadc_get_fw_channel_data()
739 prop->avg_samples = VADC_DEF_AVG_SAMPLES; in vadc_get_fw_channel_data()
743 prop->calibration = VADC_CALIB_RATIOMETRIC; in vadc_get_fw_channel_data()
745 prop->calibration = VADC_CALIB_ABSOLUTE; in vadc_get_fw_channel_data()
760 vadc->nchannels = device_get_child_node_count(vadc->dev); in vadc_get_fw_data()
761 if (!vadc->nchannels) in vadc_get_fw_data()
762 return -EINVAL; in vadc_get_fw_data()
764 vadc->iio_chans = devm_kcalloc(vadc->dev, vadc->nchannels, in vadc_get_fw_data()
765 sizeof(*vadc->iio_chans), GFP_KERNEL); in vadc_get_fw_data()
766 if (!vadc->iio_chans) in vadc_get_fw_data()
767 return -ENOMEM; in vadc_get_fw_data()
769 vadc->chan_props = devm_kcalloc(vadc->dev, vadc->nchannels, in vadc_get_fw_data()
770 sizeof(*vadc->chan_props), GFP_KERNEL); in vadc_get_fw_data()
771 if (!vadc->chan_props) in vadc_get_fw_data()
772 return -ENOMEM; in vadc_get_fw_data()
774 iio_chan = vadc->iio_chans; in vadc_get_fw_data()
776 device_for_each_child_node_scoped(vadc->dev, child) { in vadc_get_fw_data()
777 ret = vadc_get_fw_channel_data(vadc->dev, &prop, child); in vadc_get_fw_data()
782 vadc->chan_props[index] = prop; in vadc_get_fw_data()
786 iio_chan->channel = prop.channel; in vadc_get_fw_data()
787 iio_chan->datasheet_name = vadc_chan->datasheet_name; in vadc_get_fw_data()
788 iio_chan->info_mask_separate = vadc_chan->info_mask; in vadc_get_fw_data()
789 iio_chan->type = vadc_chan->type; in vadc_get_fw_data()
790 iio_chan->indexed = 1; in vadc_get_fw_data()
791 iio_chan->address = index++; in vadc_get_fw_data()
798 dev_err(vadc->dev, "Please define 1.25V channel\n"); in vadc_get_fw_data()
799 return -ENODEV; in vadc_get_fw_data()
803 dev_err(vadc->dev, "Please define 0.625V channel\n"); in vadc_get_fw_data()
804 return -ENODEV; in vadc_get_fw_data()
808 dev_err(vadc->dev, "Please define VDD channel\n"); in vadc_get_fw_data()
809 return -ENODEV; in vadc_get_fw_data()
813 dev_err(vadc->dev, "Please define GND channel\n"); in vadc_get_fw_data()
814 return -ENODEV; in vadc_get_fw_data()
824 complete(&vadc->complete); in vadc_isr()
839 dev_err(vadc->dev, "%d is not ADC\n", val); in vadc_check_revision()
840 return -ENODEV; in vadc_check_revision()
848 dev_err(vadc->dev, "%d is not VADC\n", val); in vadc_check_revision()
849 return -ENODEV; in vadc_check_revision()
857 dev_err(vadc->dev, "revision %d not supported\n", val); in vadc_check_revision()
858 return -ENODEV; in vadc_check_revision()
866 struct device *dev = &pdev->dev; in vadc_probe()
873 regmap = dev_get_regmap(dev->parent, NULL); in vadc_probe()
875 return -ENODEV; in vadc_probe()
883 return -ENOMEM; in vadc_probe()
886 vadc->regmap = regmap; in vadc_probe()
887 vadc->dev = dev; in vadc_probe()
888 vadc->base = reg; in vadc_probe()
889 vadc->are_ref_measured = false; in vadc_probe()
890 init_completion(&vadc->complete); in vadc_probe()
891 mutex_init(&vadc->lock); in vadc_probe()
903 if (irq_eoc == -EPROBE_DEFER || irq_eoc == -EINVAL) in vadc_probe()
905 vadc->poll_eoc = true; in vadc_probe()
908 "spmi-vadc", vadc); in vadc_probe()
923 indio_dev->name = pdev->name; in vadc_probe()
924 indio_dev->modes = INDIO_DIRECT_MODE; in vadc_probe()
925 indio_dev->info = &vadc_info; in vadc_probe()
926 indio_dev->channels = vadc->iio_chans; in vadc_probe()
927 indio_dev->num_channels = vadc->nchannels; in vadc_probe()
933 { .compatible = "qcom,spmi-vadc" },
940 .name = "qcom-spmi-vadc",
947 MODULE_ALIAS("platform:qcom-spmi-vadc");
950 MODULE_AUTHOR("Stanimir Varbanov <svarbanov@mm-sol.com>");
951 MODULE_AUTHOR("Ivan T. Ivanov <iivanov@mm-sol.com>");