Lines Matching +full:hw +full:- +full:settle +full:- +full:time

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>
22 #include <dt-bindings/iio/qcom,spmi-vadc.h>
75 * struct vadc_channel_prop - VADC channel property.
80 * @hw_settle_time: the time between AMUX being configured and the
98 * struct vadc_priv - VADC private structure.
138 return regmap_bulk_read(vadc->regmap, vadc->base + offset, data, 1); in vadc_read()
143 return regmap_write(vadc->regmap, vadc->base + offset, data); in vadc_write()
202 dev_err(vadc->dev, in vadc_show_status()
221 ret = vadc_write(vadc, VADC_ADC_CH_SEL_CTL, prop->channel); in vadc_configure()
226 decimation = prop->decimation << VADC_ADC_DIG_DEC_RATIO_SEL_SHIFT; in vadc_configure()
231 /* HW settle time delay */ in vadc_configure()
232 ret = vadc_write(vadc, VADC_HW_SETTLE_DELAY, prop->hw_settle_time); in vadc_configure()
236 ret = vadc_write(vadc, VADC_FAST_AVG_CTL, prop->avg_samples); in vadc_configure()
240 if (prop->avg_samples) in vadc_configure()
270 return -ETIMEDOUT; in vadc_poll_wait_eoc()
277 ret = regmap_bulk_read(vadc->regmap, vadc->base + VADC_DATA, data, 2); in vadc_read_result()
291 for (i = 0; i < vadc->nchannels; i++) in vadc_get_channel()
292 if (vadc->chan_props[i].channel == num) in vadc_get_channel()
293 return &vadc->chan_props[i]; in vadc_get_channel()
295 dev_dbg(vadc->dev, "no such channel %02x\n", num); in vadc_get_channel()
306 mutex_lock(&vadc->lock); in vadc_do_conversion()
312 if (!vadc->poll_eoc) in vadc_do_conversion()
313 reinit_completion(&vadc->complete); in vadc_do_conversion()
323 timeout = BIT(prop->avg_samples) * VADC_CONV_TIME_MIN_US * 2; in vadc_do_conversion()
325 if (vadc->poll_eoc) { in vadc_do_conversion()
328 ret = wait_for_completion_timeout(&vadc->complete, timeout); in vadc_do_conversion()
330 ret = -ETIMEDOUT; in vadc_do_conversion()
345 dev_err(vadc->dev, "conversion failed\n"); in vadc_do_conversion()
347 mutex_unlock(&vadc->lock); in vadc_do_conversion()
357 vadc->graph[VADC_CALIB_RATIOMETRIC].dx = VADC_RATIOMETRIC_RANGE; in vadc_measure_ref_points()
358 vadc->graph[VADC_CALIB_ABSOLUTE].dx = VADC_ABSOLUTE_RANGE_UV; in vadc_measure_ref_points()
375 ret = -EINVAL; in vadc_measure_ref_points()
379 vadc->graph[VADC_CALIB_ABSOLUTE].dy = read_1 - read_2; in vadc_measure_ref_points()
380 vadc->graph[VADC_CALIB_ABSOLUTE].gnd = read_2; in vadc_measure_ref_points()
394 ret = -EINVAL; in vadc_measure_ref_points()
398 vadc->graph[VADC_CALIB_RATIOMETRIC].dy = read_1 - read_2; in vadc_measure_ref_points()
399 vadc->graph[VADC_CALIB_RATIOMETRIC].gnd = read_2; in vadc_measure_ref_points()
402 dev_err(vadc->dev, "measure reference points failed\n"); in vadc_measure_ref_points()
417 return -EINVAL; in vadc_prescaling_from_dt()
425 return -EINVAL; in vadc_hw_settle_time_from_dt()
438 return -EINVAL; in vadc_avg_samples_from_dt()
454 prop = &vadc->chan_props[chan->address]; in vadc_read_raw()
459 ret = qcom_vadc_scale(prop->scale_fn_type, in vadc_read_raw()
460 &vadc->graph[prop->calibration], in vadc_read_raw()
461 &vadc_prescale_ratios[prop->prescale], in vadc_read_raw()
462 (prop->calibration == VADC_CALIB_ABSOLUTE), in vadc_read_raw()
469 prop = &vadc->chan_props[chan->address]; in vadc_read_raw()
477 ret = -EINVAL; in vadc_read_raw()
490 for (i = 0; i < vadc->nchannels; i++) in vadc_of_xlate()
491 if (vadc->iio_chans[i].channel == iiospec->args[0]) in vadc_of_xlate()
494 return -EINVAL; in vadc_of_xlate()
654 const char *name = node->name; in vadc_get_dt_channel_data()
666 return -EINVAL; in vadc_get_dt_channel_data()
670 prop->channel = chan; in vadc_get_dt_channel_data()
680 prop->decimation = ret; in vadc_get_dt_channel_data()
682 prop->decimation = VADC_DEF_DECIMATION; in vadc_get_dt_channel_data()
685 ret = of_property_read_u32_array(node, "qcom,pre-scaling", varr, 2); in vadc_get_dt_channel_data()
689 dev_err(dev, "%02x invalid pre-scaling <%d %d>\n", in vadc_get_dt_channel_data()
693 prop->prescale = ret; in vadc_get_dt_channel_data()
695 prop->prescale = vadc_chans[prop->channel].prescale_index; in vadc_get_dt_channel_data()
698 ret = of_property_read_u32(node, "qcom,hw-settle-time", &value); in vadc_get_dt_channel_data()
702 dev_err(dev, "%02x invalid hw-settle-time %d us\n", in vadc_get_dt_channel_data()
706 prop->hw_settle_time = ret; in vadc_get_dt_channel_data()
708 prop->hw_settle_time = VADC_DEF_HW_SETTLE_TIME; in vadc_get_dt_channel_data()
711 ret = of_property_read_u32(node, "qcom,avg-samples", &value); in vadc_get_dt_channel_data()
715 dev_err(dev, "%02x invalid avg-samples %d\n", in vadc_get_dt_channel_data()
719 prop->avg_samples = ret; in vadc_get_dt_channel_data()
721 prop->avg_samples = VADC_DEF_AVG_SAMPLES; in vadc_get_dt_channel_data()
725 prop->calibration = VADC_CALIB_RATIOMETRIC; in vadc_get_dt_channel_data()
727 prop->calibration = VADC_CALIB_ABSOLUTE; in vadc_get_dt_channel_data()
743 vadc->nchannels = of_get_available_child_count(node); in vadc_get_dt_data()
744 if (!vadc->nchannels) in vadc_get_dt_data()
745 return -EINVAL; in vadc_get_dt_data()
747 vadc->iio_chans = devm_kcalloc(vadc->dev, vadc->nchannels, in vadc_get_dt_data()
748 sizeof(*vadc->iio_chans), GFP_KERNEL); in vadc_get_dt_data()
749 if (!vadc->iio_chans) in vadc_get_dt_data()
750 return -ENOMEM; in vadc_get_dt_data()
752 vadc->chan_props = devm_kcalloc(vadc->dev, vadc->nchannels, in vadc_get_dt_data()
753 sizeof(*vadc->chan_props), GFP_KERNEL); in vadc_get_dt_data()
754 if (!vadc->chan_props) in vadc_get_dt_data()
755 return -ENOMEM; in vadc_get_dt_data()
757 iio_chan = vadc->iio_chans; in vadc_get_dt_data()
760 ret = vadc_get_dt_channel_data(vadc->dev, &prop, child); in vadc_get_dt_data()
767 vadc->chan_props[index] = prop; in vadc_get_dt_data()
771 iio_chan->channel = prop.channel; in vadc_get_dt_data()
772 iio_chan->datasheet_name = vadc_chan->datasheet_name; in vadc_get_dt_data()
773 iio_chan->info_mask_separate = vadc_chan->info_mask; in vadc_get_dt_data()
774 iio_chan->type = vadc_chan->type; in vadc_get_dt_data()
775 iio_chan->indexed = 1; in vadc_get_dt_data()
776 iio_chan->address = index++; in vadc_get_dt_data()
783 dev_err(vadc->dev, "Please define 1.25V channel\n"); in vadc_get_dt_data()
784 return -ENODEV; in vadc_get_dt_data()
788 dev_err(vadc->dev, "Please define 0.625V channel\n"); in vadc_get_dt_data()
789 return -ENODEV; in vadc_get_dt_data()
793 dev_err(vadc->dev, "Please define VDD channel\n"); in vadc_get_dt_data()
794 return -ENODEV; in vadc_get_dt_data()
798 dev_err(vadc->dev, "Please define GND channel\n"); in vadc_get_dt_data()
799 return -ENODEV; in vadc_get_dt_data()
809 complete(&vadc->complete); in vadc_isr()
824 dev_err(vadc->dev, "%d is not ADC\n", val); in vadc_check_revision()
825 return -ENODEV; in vadc_check_revision()
833 dev_err(vadc->dev, "%d is not VADC\n", val); in vadc_check_revision()
834 return -ENODEV; in vadc_check_revision()
842 dev_err(vadc->dev, "revision %d not supported\n", val); in vadc_check_revision()
843 return -ENODEV; in vadc_check_revision()
851 struct device_node *node = pdev->dev.of_node; in vadc_probe()
852 struct device *dev = &pdev->dev; in vadc_probe()
859 regmap = dev_get_regmap(dev->parent, NULL); in vadc_probe()
861 return -ENODEV; in vadc_probe()
869 return -ENOMEM; in vadc_probe()
872 vadc->regmap = regmap; in vadc_probe()
873 vadc->dev = dev; in vadc_probe()
874 vadc->base = reg; in vadc_probe()
875 vadc->are_ref_measured = false; in vadc_probe()
876 init_completion(&vadc->complete); in vadc_probe()
877 mutex_init(&vadc->lock); in vadc_probe()
889 if (irq_eoc == -EPROBE_DEFER || irq_eoc == -EINVAL) in vadc_probe()
891 vadc->poll_eoc = true; in vadc_probe()
894 "spmi-vadc", vadc); in vadc_probe()
909 indio_dev->name = pdev->name; in vadc_probe()
910 indio_dev->modes = INDIO_DIRECT_MODE; in vadc_probe()
911 indio_dev->info = &vadc_info; in vadc_probe()
912 indio_dev->channels = vadc->iio_chans; in vadc_probe()
913 indio_dev->num_channels = vadc->nchannels; in vadc_probe()
919 { .compatible = "qcom,spmi-vadc" },
926 .name = "qcom-spmi-vadc",
933 MODULE_ALIAS("platform:qcom-spmi-vadc");
936 MODULE_AUTHOR("Stanimir Varbanov <svarbanov@mm-sol.com>");
937 MODULE_AUTHOR("Ivan T. Ivanov <iivanov@mm-sol.com>");