Lines Matching full:vadc
29 #include <dt-bindings/iio/qcom,spmi-vadc.h>
31 #include "qcom-vadc-common.h"
33 /* VADC register and bit definitions */
84 * struct vadc_channel_prop - VADC channel property.
107 * struct vadc_priv - VADC private structure.
111 * @nchannels: number of VADC channels.
112 * @chan_props: array of VADC channel properties.
116 * @complete: VADC result notification after interrupt is received.
145 static int vadc_read(struct vadc_priv *vadc, u16 offset, u8 *data) in vadc_read() argument
147 return regmap_bulk_read(vadc->regmap, vadc->base + offset, data, 1); in vadc_read()
150 static int vadc_write(struct vadc_priv *vadc, u16 offset, u8 data) in vadc_write() argument
152 return regmap_write(vadc->regmap, vadc->base + offset, data); in vadc_write()
155 static int vadc_reset(struct vadc_priv *vadc) in vadc_reset() argument
160 ret = vadc_write(vadc, VADC_ACCESS, VADC_ACCESS_DATA); in vadc_reset()
164 ret = vadc_read(vadc, VADC_PERH_RESET_CTL3, &data); in vadc_reset()
168 ret = vadc_write(vadc, VADC_ACCESS, VADC_ACCESS_DATA); in vadc_reset()
174 return vadc_write(vadc, VADC_PERH_RESET_CTL3, data); in vadc_reset()
177 static int vadc_set_state(struct vadc_priv *vadc, bool state) in vadc_set_state() argument
179 return vadc_write(vadc, VADC_EN_CTL1, state ? VADC_EN_CTL1_SET : 0); in vadc_set_state()
182 static void vadc_show_status(struct vadc_priv *vadc) in vadc_show_status() argument
187 ret = vadc_read(vadc, VADC_MODE_CTL, &mode); in vadc_show_status()
191 ret = vadc_read(vadc, VADC_ADC_DIG_PARAM, &dig); in vadc_show_status()
195 ret = vadc_read(vadc, VADC_ADC_CH_SEL_CTL, &chan); in vadc_show_status()
199 ret = vadc_read(vadc, VADC_CONV_REQ, &req); in vadc_show_status()
203 ret = vadc_read(vadc, VADC_STATUS1, &sta1); in vadc_show_status()
207 ret = vadc_read(vadc, VADC_EN_CTL1, &en); in vadc_show_status()
211 dev_err(vadc->dev, in vadc_show_status()
216 static int vadc_configure(struct vadc_priv *vadc, in vadc_configure() argument
225 ret = vadc_write(vadc, VADC_MODE_CTL, mode_ctrl); in vadc_configure()
230 ret = vadc_write(vadc, VADC_ADC_CH_SEL_CTL, prop->channel); in vadc_configure()
236 ret = vadc_write(vadc, VADC_ADC_DIG_PARAM, decimation); in vadc_configure()
241 ret = vadc_write(vadc, VADC_HW_SETTLE_DELAY, prop->hw_settle_time); in vadc_configure()
245 ret = vadc_write(vadc, VADC_FAST_AVG_CTL, prop->avg_samples); in vadc_configure()
250 ret = vadc_write(vadc, VADC_FAST_AVG_EN, VADC_FAST_AVG_EN_SET); in vadc_configure()
252 ret = vadc_write(vadc, VADC_FAST_AVG_EN, 0); in vadc_configure()
257 static int vadc_poll_wait_eoc(struct vadc_priv *vadc, unsigned int interval_us) in vadc_poll_wait_eoc() argument
266 ret = vadc_read(vadc, VADC_STATUS1, &sta1); in vadc_poll_wait_eoc()
277 vadc_show_status(vadc); in vadc_poll_wait_eoc()
282 static int vadc_read_result(struct vadc_priv *vadc, u16 *data) in vadc_read_result() argument
286 ret = regmap_bulk_read(vadc->regmap, vadc->base + VADC_DATA, data, 2); in vadc_read_result()
295 static struct vadc_channel_prop *vadc_get_channel(struct vadc_priv *vadc, in vadc_get_channel() argument
300 for (i = 0; i < vadc->nchannels; i++) in vadc_get_channel()
301 if (vadc->chan_props[i].channel == num) in vadc_get_channel()
302 return &vadc->chan_props[i]; in vadc_get_channel()
304 dev_dbg(vadc->dev, "no such channel %02x\n", num); in vadc_get_channel()
309 static int vadc_do_conversion(struct vadc_priv *vadc, in vadc_do_conversion() argument
315 mutex_lock(&vadc->lock); in vadc_do_conversion()
317 ret = vadc_configure(vadc, prop); in vadc_do_conversion()
321 if (!vadc->poll_eoc) in vadc_do_conversion()
322 reinit_completion(&vadc->complete); in vadc_do_conversion()
324 ret = vadc_set_state(vadc, true); in vadc_do_conversion()
328 ret = vadc_write(vadc, VADC_CONV_REQ, VADC_CONV_REQ_SET); in vadc_do_conversion()
334 if (vadc->poll_eoc) { in vadc_do_conversion()
335 ret = vadc_poll_wait_eoc(vadc, timeout); in vadc_do_conversion()
337 ret = wait_for_completion_timeout(&vadc->complete, timeout); in vadc_do_conversion()
344 ret = vadc_poll_wait_eoc(vadc, VADC_CONV_TIME_MIN_US); in vadc_do_conversion()
349 ret = vadc_read_result(vadc, data); in vadc_do_conversion()
352 vadc_set_state(vadc, false); in vadc_do_conversion()
354 dev_err(vadc->dev, "conversion failed\n"); in vadc_do_conversion()
356 mutex_unlock(&vadc->lock); in vadc_do_conversion()
360 static int vadc_measure_ref_points(struct vadc_priv *vadc) in vadc_measure_ref_points() argument
366 vadc->graph[VADC_CALIB_RATIOMETRIC].dx = VADC_RATIOMETRIC_RANGE; in vadc_measure_ref_points()
367 vadc->graph[VADC_CALIB_ABSOLUTE].dx = VADC_ABSOLUTE_RANGE_UV; in vadc_measure_ref_points()
369 prop = vadc_get_channel(vadc, VADC_REF_1250MV); in vadc_measure_ref_points()
370 ret = vadc_do_conversion(vadc, prop, &read_1); in vadc_measure_ref_points()
375 prop = vadc_get_channel(vadc, VADC_SPARE1); in vadc_measure_ref_points()
377 prop = vadc_get_channel(vadc, VADC_REF_625MV); in vadc_measure_ref_points()
379 ret = vadc_do_conversion(vadc, prop, &read_2); in vadc_measure_ref_points()
388 vadc->graph[VADC_CALIB_ABSOLUTE].dy = read_1 - read_2; in vadc_measure_ref_points()
389 vadc->graph[VADC_CALIB_ABSOLUTE].gnd = read_2; in vadc_measure_ref_points()
392 prop = vadc_get_channel(vadc, VADC_VDD_VADC); in vadc_measure_ref_points()
393 ret = vadc_do_conversion(vadc, prop, &read_1); in vadc_measure_ref_points()
397 prop = vadc_get_channel(vadc, VADC_GND_REF); in vadc_measure_ref_points()
398 ret = vadc_do_conversion(vadc, prop, &read_2); in vadc_measure_ref_points()
407 vadc->graph[VADC_CALIB_RATIOMETRIC].dy = read_1 - read_2; in vadc_measure_ref_points()
408 vadc->graph[VADC_CALIB_RATIOMETRIC].gnd = read_2; in vadc_measure_ref_points()
411 dev_err(vadc->dev, "measure reference points failed\n"); in vadc_measure_ref_points()
456 struct vadc_priv *vadc = iio_priv(indio_dev); in vadc_read_raw() local
463 prop = &vadc->chan_props[chan->address]; in vadc_read_raw()
464 ret = vadc_do_conversion(vadc, prop, &adc_code); in vadc_read_raw()
469 &vadc->graph[prop->calibration], in vadc_read_raw()
478 prop = &vadc->chan_props[chan->address]; in vadc_read_raw()
479 ret = vadc_do_conversion(vadc, prop, &adc_code); in vadc_read_raw()
496 struct vadc_priv *vadc = iio_priv(indio_dev); in vadc_of_xlate() local
499 for (i = 0; i < vadc->nchannels; i++) in vadc_of_xlate()
500 if (vadc->iio_chans[i].channel == iiospec->args[0]) in vadc_of_xlate()
743 static int vadc_get_dt_data(struct vadc_priv *vadc, struct device_node *node) in vadc_get_dt_data() argument
752 vadc->nchannels = of_get_available_child_count(node); in vadc_get_dt_data()
753 if (!vadc->nchannels) in vadc_get_dt_data()
756 vadc->iio_chans = devm_kcalloc(vadc->dev, vadc->nchannels, in vadc_get_dt_data()
757 sizeof(*vadc->iio_chans), GFP_KERNEL); in vadc_get_dt_data()
758 if (!vadc->iio_chans) in vadc_get_dt_data()
761 vadc->chan_props = devm_kcalloc(vadc->dev, vadc->nchannels, in vadc_get_dt_data()
762 sizeof(*vadc->chan_props), GFP_KERNEL); in vadc_get_dt_data()
763 if (!vadc->chan_props) in vadc_get_dt_data()
766 iio_chan = vadc->iio_chans; in vadc_get_dt_data()
769 ret = vadc_get_dt_channel_data(vadc->dev, &prop, child); in vadc_get_dt_data()
776 vadc->chan_props[index] = prop; in vadc_get_dt_data()
791 if (!vadc_get_channel(vadc, VADC_REF_1250MV)) { in vadc_get_dt_data()
792 dev_err(vadc->dev, "Please define 1.25V channel\n"); in vadc_get_dt_data()
796 if (!vadc_get_channel(vadc, VADC_REF_625MV)) { in vadc_get_dt_data()
797 dev_err(vadc->dev, "Please define 0.625V channel\n"); in vadc_get_dt_data()
801 if (!vadc_get_channel(vadc, VADC_VDD_VADC)) { in vadc_get_dt_data()
802 dev_err(vadc->dev, "Please define VDD channel\n"); in vadc_get_dt_data()
806 if (!vadc_get_channel(vadc, VADC_GND_REF)) { in vadc_get_dt_data()
807 dev_err(vadc->dev, "Please define GND channel\n"); in vadc_get_dt_data()
816 struct vadc_priv *vadc = dev_id; in vadc_isr() local
818 complete(&vadc->complete); in vadc_isr()
823 static int vadc_check_revision(struct vadc_priv *vadc) in vadc_check_revision() argument
828 ret = vadc_read(vadc, VADC_PERPH_TYPE, &val); in vadc_check_revision()
833 dev_err(vadc->dev, "%d is not ADC\n", val); in vadc_check_revision()
837 ret = vadc_read(vadc, VADC_PERPH_SUBTYPE, &val); in vadc_check_revision()
842 dev_err(vadc->dev, "%d is not VADC\n", val); in vadc_check_revision()
846 ret = vadc_read(vadc, VADC_REVISION2, &val); in vadc_check_revision()
851 dev_err(vadc->dev, "revision %d not supported\n", val); in vadc_check_revision()
863 struct vadc_priv *vadc; in vadc_probe() local
876 indio_dev = devm_iio_device_alloc(dev, sizeof(*vadc)); in vadc_probe()
880 vadc = iio_priv(indio_dev); in vadc_probe()
881 vadc->regmap = regmap; in vadc_probe()
882 vadc->dev = dev; in vadc_probe()
883 vadc->base = reg; in vadc_probe()
884 vadc->are_ref_measured = false; in vadc_probe()
885 init_completion(&vadc->complete); in vadc_probe()
886 mutex_init(&vadc->lock); in vadc_probe()
888 ret = vadc_check_revision(vadc); in vadc_probe()
892 ret = vadc_get_dt_data(vadc, node); in vadc_probe()
900 vadc->poll_eoc = true; in vadc_probe()
903 "spmi-vadc", vadc); in vadc_probe()
908 ret = vadc_reset(vadc); in vadc_probe()
914 ret = vadc_measure_ref_points(vadc); in vadc_probe()
923 indio_dev->channels = vadc->iio_chans; in vadc_probe()
924 indio_dev->num_channels = vadc->nchannels; in vadc_probe()
930 { .compatible = "qcom,spmi-vadc" },
937 .name = "qcom-spmi-vadc",
944 MODULE_ALIAS("platform:qcom-spmi-vadc");