Lines Matching +full:adc +full:- +full:reserved +full:- +full:channels
1 // SPDX-License-Identifier: GPL-2.0-only
7 * specific-purpose and general purpose ADC converters and channels.
13 #include <linux/iio/adc/qcom-vadc-common.h>
27 * Qualcomm tree. Their kernel has two out-of-tree drivers for the ADC:
28 * drivers/misc/pmic8058-xoadc.c
29 * drivers/hwmon/pm8xxx-adc.c
57 /* Proper ADC registers */
99 * On a later ADC the decimation factors are defined as
123 * Physical channels which MUST exist on all PM variants in order to provide
155 * struct xoadc_channel - encodes channel properties and defaults
162 * @prescale: the channels have hard-coded prescale ratios defined
167 * ADC code to the value that IIO expects, in uV or millicelsius
185 * struct xoadc_variant - encodes the XOADC variant characteristics
187 * @channels: the hardware channels and respective settings and defaults
196 const struct xoadc_channel *channels; member
230 * Taken from arch/arm/mach-msm/board-9615.c in the vendor tree:
247 * Taken from arch/arm/mach-msm/board-8930-pmic.c in the vendor tree:
272 * This was created by cross-referencing the vendor tree
273 * arch/arm/mach-msm/board-msm8x60.c msm_adc_channels_data[]
275 * configuration for these channels on an MSM8x60 i.e. PM8058
285 * AMUX channels 5 thru 9 are referred to as MPP5 thru MPP9 in
287 * channels just like any other. They are connected to a switching
289 * 1-to-1 onto MPP5 thru 9, so naming them MPP5 thru MPP9 is
303 /* There are also "unity" and divided by 3 channels (prescaler) but noone is using them */
308 * The PM8921 has some pre-muxing on its channels, this comes from the vendor tree
309 * include/linux/mfd/pm8xxx/pm8xxx-adc.h
310 * board-flo-pmic.c (Nexus 7) and board-8064-pmic.c
316 /* channel "ICHG" is reserved and not used on PM8921 */
319 /* CHAN 6 & 7 (MPP1 & MPP2) are reserved for MPP channels on PM8921 */
329 /* The following channels have premux bit 0 set to 1 (all end in 4) */
348 /* The following channels have premux bit 1 set to 1 (all end in 8) */
371 * struct pm8xxx_chan_info - ADC channel information
389 * struct pm8xxx_xoadc - state container for the XOADC
394 * characteristics of the channels, and sensible default settings
395 * @nchans: number of channels, configured by the device tree
396 * @chans: the channel information per-channel, configured by the device tree
419 struct pm8xxx_xoadc *adc = iio_priv(indio_dev); in pm8xxx_eoc_irq() local
421 complete(&adc->complete); in pm8xxx_eoc_irq()
427 pm8xxx_get_channel(struct pm8xxx_xoadc *adc, u8 chan) in pm8xxx_get_channel() argument
431 for (i = 0; i < adc->nchans; i++) { in pm8xxx_get_channel()
432 struct pm8xxx_chan_info *ch = &adc->chans[i]; in pm8xxx_get_channel()
433 if (ch->hwchan->amux_channel == chan) in pm8xxx_get_channel()
439 static int pm8xxx_read_channel_rsv(struct pm8xxx_xoadc *adc, in pm8xxx_read_channel_rsv() argument
449 dev_dbg(adc->dev, "read channel \"%s\", amux %d, prescale/mux: %d, rsv %d\n", in pm8xxx_read_channel_rsv()
450 ch->name, ch->hwchan->amux_channel, ch->hwchan->pre_scale_mux, rsv); in pm8xxx_read_channel_rsv()
452 mutex_lock(&adc->lock); in pm8xxx_read_channel_rsv()
455 val = ch->hwchan->amux_channel << ADC_AMUX_SEL_SHIFT; in pm8xxx_read_channel_rsv()
456 val |= ch->hwchan->pre_scale_mux << ADC_AMUX_PREMUX_SHIFT; in pm8xxx_read_channel_rsv()
457 ret = regmap_write(adc->map, ADC_ARB_USRP_AMUX_CNTRL, val); in pm8xxx_read_channel_rsv()
464 if (adc->variant->broken_ratiometric && !force_ratiometric) { in pm8xxx_read_channel_rsv()
467 * reflected in the vendor tree drivers/misc/pmix8058-xoadc.c in pm8xxx_read_channel_rsv()
481 if (ch->hwchan->amux_channel == PM8XXX_CHANNEL_MUXOFF) in pm8xxx_read_channel_rsv()
487 rsvval = (ch->amux_ip_rsv << ADC_RSV_IP_SEL_SHIFT) | in pm8xxx_read_channel_rsv()
494 ret = regmap_update_bits(adc->map, in pm8xxx_read_channel_rsv()
501 ret = regmap_write(adc->map, ADC_ARB_USRP_ANA_PARAM, in pm8xxx_read_channel_rsv()
507 ret = regmap_write(adc->map, ADC_ARB_USRP_DIG_PARAM, in pm8xxx_read_channel_rsv()
510 ch->decimation << ADC_DIG_PARAM_DEC_SHIFT); in pm8xxx_read_channel_rsv()
514 ret = regmap_write(adc->map, ADC_ARB_USRP_ANA_PARAM, in pm8xxx_read_channel_rsv()
520 ret = regmap_write(adc->map, ADC_ARB_USRP_CNTRL, in pm8xxx_read_channel_rsv()
524 ret = regmap_write(adc->map, ADC_ARB_USRP_CNTRL, in pm8xxx_read_channel_rsv()
531 reinit_completion(&adc->complete); in pm8xxx_read_channel_rsv()
532 ret = regmap_write(adc->map, ADC_ARB_USRP_CNTRL, in pm8xxx_read_channel_rsv()
539 ret = wait_for_completion_timeout(&adc->complete, in pm8xxx_read_channel_rsv()
542 dev_err(adc->dev, "conversion timed out\n"); in pm8xxx_read_channel_rsv()
543 ret = -ETIMEDOUT; in pm8xxx_read_channel_rsv()
547 ret = regmap_read(adc->map, ADC_ARB_USRP_DATA0, &val); in pm8xxx_read_channel_rsv()
551 ret = regmap_read(adc->map, ADC_ARB_USRP_DATA1, &val); in pm8xxx_read_channel_rsv()
557 /* Turn off the ADC by setting the arbiter to 0 twice */ in pm8xxx_read_channel_rsv()
558 ret = regmap_write(adc->map, ADC_ARB_USRP_CNTRL, 0); in pm8xxx_read_channel_rsv()
561 ret = regmap_write(adc->map, ADC_ARB_USRP_CNTRL, 0); in pm8xxx_read_channel_rsv()
566 mutex_unlock(&adc->lock); in pm8xxx_read_channel_rsv()
570 static int pm8xxx_read_channel(struct pm8xxx_xoadc *adc, in pm8xxx_read_channel() argument
579 return pm8xxx_read_channel_rsv(adc, ch, 0xff, adc_code, false); in pm8xxx_read_channel()
582 static int pm8xxx_calibrate_device(struct pm8xxx_xoadc *adc) in pm8xxx_calibrate_device() argument
591 adc->graph[VADC_CALIB_ABSOLUTE].dx = VADC_ABSOLUTE_RANGE_UV; in pm8xxx_calibrate_device()
592 adc->graph[VADC_CALIB_RATIOMETRIC].dx = VADC_RATIOMETRIC_RANGE; in pm8xxx_calibrate_device()
595 ch = pm8xxx_get_channel(adc, PM8XXX_CHANNEL_125V); in pm8xxx_calibrate_device()
597 return -ENODEV; in pm8xxx_calibrate_device()
598 ret = pm8xxx_read_channel(adc, ch, &read_1250v); in pm8xxx_calibrate_device()
600 dev_err(adc->dev, "could not read 1.25V reference channel\n"); in pm8xxx_calibrate_device()
601 return -ENODEV; in pm8xxx_calibrate_device()
603 ch = pm8xxx_get_channel(adc, PM8XXX_CHANNEL_INTERNAL); in pm8xxx_calibrate_device()
605 return -ENODEV; in pm8xxx_calibrate_device()
606 ret = pm8xxx_read_channel(adc, ch, &read_0625v); in pm8xxx_calibrate_device()
608 dev_err(adc->dev, "could not read 0.625V reference channel\n"); in pm8xxx_calibrate_device()
609 return -ENODEV; in pm8xxx_calibrate_device()
612 dev_err(adc->dev, "read same ADC code for 1.25V and 0.625V\n"); in pm8xxx_calibrate_device()
613 return -ENODEV; in pm8xxx_calibrate_device()
616 adc->graph[VADC_CALIB_ABSOLUTE].dy = read_1250v - read_0625v; in pm8xxx_calibrate_device()
617 adc->graph[VADC_CALIB_ABSOLUTE].gnd = read_0625v; in pm8xxx_calibrate_device()
619 dev_info(adc->dev, "absolute calibration dx = %d uV, dy = %d units\n", in pm8xxx_calibrate_device()
620 VADC_ABSOLUTE_RANGE_UV, adc->graph[VADC_CALIB_ABSOLUTE].dy); in pm8xxx_calibrate_device()
623 ch = pm8xxx_get_channel(adc, PM8XXX_CHANNEL_MUXOFF); in pm8xxx_calibrate_device()
625 return -ENODEV; in pm8xxx_calibrate_device()
626 ret = pm8xxx_read_channel_rsv(adc, ch, AMUX_RSV5, in pm8xxx_calibrate_device()
629 dev_err(adc->dev, "could not read MUXOFF reference channel\n"); in pm8xxx_calibrate_device()
630 return -ENODEV; in pm8xxx_calibrate_device()
632 ret = pm8xxx_read_channel_rsv(adc, ch, AMUX_RSV4, in pm8xxx_calibrate_device()
635 dev_err(adc->dev, "could not read MUXOFF reference channel\n"); in pm8xxx_calibrate_device()
636 return -ENODEV; in pm8xxx_calibrate_device()
638 adc->graph[VADC_CALIB_RATIOMETRIC].dy = in pm8xxx_calibrate_device()
639 read_nomux_rsv5 - read_nomux_rsv4; in pm8xxx_calibrate_device()
640 adc->graph[VADC_CALIB_RATIOMETRIC].gnd = read_nomux_rsv4; in pm8xxx_calibrate_device()
642 dev_info(adc->dev, "ratiometric calibration dx = %d, dy = %d units\n", in pm8xxx_calibrate_device()
644 adc->graph[VADC_CALIB_RATIOMETRIC].dy); in pm8xxx_calibrate_device()
653 struct pm8xxx_xoadc *adc = iio_priv(indio_dev); in pm8xxx_read_raw() local
660 ch = pm8xxx_get_channel(adc, chan->address); in pm8xxx_read_raw()
662 dev_err(adc->dev, "no such channel %lu\n", in pm8xxx_read_raw()
663 chan->address); in pm8xxx_read_raw()
664 return -EINVAL; in pm8xxx_read_raw()
666 ret = pm8xxx_read_channel(adc, ch, &adc_code); in pm8xxx_read_raw()
670 ret = qcom_vadc_scale(ch->hwchan->scale_fn_type, in pm8xxx_read_raw()
671 &adc->graph[ch->calibration], in pm8xxx_read_raw()
672 &ch->hwchan->prescale, in pm8xxx_read_raw()
673 (ch->calibration == VADC_CALIB_ABSOLUTE), in pm8xxx_read_raw()
680 ch = pm8xxx_get_channel(adc, chan->address); in pm8xxx_read_raw()
682 dev_err(adc->dev, "no such channel %lu\n", in pm8xxx_read_raw()
683 chan->address); in pm8xxx_read_raw()
684 return -EINVAL; in pm8xxx_read_raw()
686 ret = pm8xxx_read_channel(adc, ch, &adc_code); in pm8xxx_read_raw()
693 return -EINVAL; in pm8xxx_read_raw()
700 struct pm8xxx_xoadc *adc = iio_priv(indio_dev); in pm8xxx_fwnode_xlate() local
709 if (iiospec->nargs != 2) { in pm8xxx_fwnode_xlate()
710 dev_err(&indio_dev->dev, "wrong number of arguments for %pfwP need 2 got %d\n", in pm8xxx_fwnode_xlate()
711 iiospec->fwnode, in pm8xxx_fwnode_xlate()
712 iiospec->nargs); in pm8xxx_fwnode_xlate()
713 return -EINVAL; in pm8xxx_fwnode_xlate()
715 pre_scale_mux = (u8)iiospec->args[0]; in pm8xxx_fwnode_xlate()
716 amux_channel = (u8)iiospec->args[1]; in pm8xxx_fwnode_xlate()
717 dev_dbg(&indio_dev->dev, "pre scale/mux: %02x, amux: %02x\n", in pm8xxx_fwnode_xlate()
721 for (i = 0; i < adc->nchans; i++) in pm8xxx_fwnode_xlate()
722 if (adc->chans[i].hwchan->pre_scale_mux == pre_scale_mux && in pm8xxx_fwnode_xlate()
723 adc->chans[i].hwchan->amux_channel == amux_channel) in pm8xxx_fwnode_xlate()
726 return -EINVAL; in pm8xxx_fwnode_xlate()
761 while (hwchan->datasheet_name) { in pm8xxx_xoadc_parse_channel()
762 if (hwchan->pre_scale_mux == pre_scale_mux && in pm8xxx_xoadc_parse_channel()
763 hwchan->amux_channel == amux_channel) in pm8xxx_xoadc_parse_channel()
769 if (!hwchan->datasheet_name) { in pm8xxx_xoadc_parse_channel()
772 return -EINVAL; in pm8xxx_xoadc_parse_channel()
774 ch->name = name; in pm8xxx_xoadc_parse_channel()
775 ch->hwchan = hwchan; in pm8xxx_xoadc_parse_channel()
777 ch->calibration = VADC_CALIB_ABSOLUTE; in pm8xxx_xoadc_parse_channel()
779 ch->decimation = VADC_DEF_DECIMATION; in pm8xxx_xoadc_parse_channel()
782 ch->calibration = VADC_CALIB_RATIOMETRIC; in pm8xxx_xoadc_parse_channel()
785 return -EINVAL; in pm8xxx_xoadc_parse_channel()
789 return -EINVAL; in pm8xxx_xoadc_parse_channel()
802 ch->decimation = ret; in pm8xxx_xoadc_parse_channel()
805 iio_chan->channel = chid; in pm8xxx_xoadc_parse_channel()
806 iio_chan->address = hwchan->amux_channel; in pm8xxx_xoadc_parse_channel()
807 iio_chan->datasheet_name = hwchan->datasheet_name; in pm8xxx_xoadc_parse_channel()
808 iio_chan->type = hwchan->type; in pm8xxx_xoadc_parse_channel()
809 /* All channels are raw or processed */ in pm8xxx_xoadc_parse_channel()
810 iio_chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | in pm8xxx_xoadc_parse_channel()
812 iio_chan->indexed = 1; in pm8xxx_xoadc_parse_channel()
816 hwchan->pre_scale_mux, hwchan->amux_channel, ch->name, in pm8xxx_xoadc_parse_channel()
817 ch->amux_ip_rsv, ch->decimation, hwchan->prescale.numerator, in pm8xxx_xoadc_parse_channel()
818 hwchan->prescale.denominator, hwchan->scale_fn_type); in pm8xxx_xoadc_parse_channel()
823 static int pm8xxx_xoadc_parse_channels(struct pm8xxx_xoadc *adc) in pm8xxx_xoadc_parse_channels() argument
830 adc->nchans = device_get_child_node_count(adc->dev); in pm8xxx_xoadc_parse_channels()
831 if (!adc->nchans) { in pm8xxx_xoadc_parse_channels()
832 dev_err(adc->dev, "no channel children\n"); in pm8xxx_xoadc_parse_channels()
833 return -ENODEV; in pm8xxx_xoadc_parse_channels()
835 dev_dbg(adc->dev, "found %d ADC channels\n", adc->nchans); in pm8xxx_xoadc_parse_channels()
837 adc->iio_chans = devm_kcalloc(adc->dev, adc->nchans, in pm8xxx_xoadc_parse_channels()
838 sizeof(*adc->iio_chans), GFP_KERNEL); in pm8xxx_xoadc_parse_channels()
839 if (!adc->iio_chans) in pm8xxx_xoadc_parse_channels()
840 return -ENOMEM; in pm8xxx_xoadc_parse_channels()
842 adc->chans = devm_kcalloc(adc->dev, adc->nchans, in pm8xxx_xoadc_parse_channels()
843 sizeof(*adc->chans), GFP_KERNEL); in pm8xxx_xoadc_parse_channels()
844 if (!adc->chans) in pm8xxx_xoadc_parse_channels()
845 return -ENOMEM; in pm8xxx_xoadc_parse_channels()
848 device_for_each_child_node(adc->dev, child) { in pm8xxx_xoadc_parse_channels()
849 ch = &adc->chans[i]; in pm8xxx_xoadc_parse_channels()
850 ret = pm8xxx_xoadc_parse_channel(adc->dev, child, in pm8xxx_xoadc_parse_channels()
851 adc->variant->channels, in pm8xxx_xoadc_parse_channels()
852 &adc->iio_chans[i], in pm8xxx_xoadc_parse_channels()
861 /* Check for required channels */ in pm8xxx_xoadc_parse_channels()
862 ch = pm8xxx_get_channel(adc, PM8XXX_CHANNEL_125V); in pm8xxx_xoadc_parse_channels()
864 dev_err(adc->dev, "missing 1.25V reference channel\n"); in pm8xxx_xoadc_parse_channels()
865 return -ENODEV; in pm8xxx_xoadc_parse_channels()
867 ch = pm8xxx_get_channel(adc, PM8XXX_CHANNEL_INTERNAL); in pm8xxx_xoadc_parse_channels()
869 dev_err(adc->dev, "missing 0.625V reference channel\n"); in pm8xxx_xoadc_parse_channels()
870 return -ENODEV; in pm8xxx_xoadc_parse_channels()
872 ch = pm8xxx_get_channel(adc, PM8XXX_CHANNEL_MUXOFF); in pm8xxx_xoadc_parse_channels()
874 dev_err(adc->dev, "missing MUXOFF reference channel\n"); in pm8xxx_xoadc_parse_channels()
875 return -ENODEV; in pm8xxx_xoadc_parse_channels()
884 struct pm8xxx_xoadc *adc; in pm8xxx_xoadc_probe() local
887 struct device *dev = &pdev->dev; in pm8xxx_xoadc_probe()
892 return -ENODEV; in pm8xxx_xoadc_probe()
894 indio_dev = devm_iio_device_alloc(dev, sizeof(*adc)); in pm8xxx_xoadc_probe()
896 return -ENOMEM; in pm8xxx_xoadc_probe()
899 adc = iio_priv(indio_dev); in pm8xxx_xoadc_probe()
900 adc->dev = dev; in pm8xxx_xoadc_probe()
901 adc->variant = variant; in pm8xxx_xoadc_probe()
902 init_completion(&adc->complete); in pm8xxx_xoadc_probe()
903 mutex_init(&adc->lock); in pm8xxx_xoadc_probe()
905 ret = pm8xxx_xoadc_parse_channels(adc); in pm8xxx_xoadc_probe()
909 map = dev_get_regmap(dev->parent, NULL); in pm8xxx_xoadc_probe()
912 return -ENODEV; in pm8xxx_xoadc_probe()
914 adc->map = map; in pm8xxx_xoadc_probe()
917 adc->vref = devm_regulator_get(dev, "xoadc-ref"); in pm8xxx_xoadc_probe()
918 if (IS_ERR(adc->vref)) in pm8xxx_xoadc_probe()
919 return dev_err_probe(dev, PTR_ERR(adc->vref), in pm8xxx_xoadc_probe()
921 ret = regulator_enable(adc->vref); in pm8xxx_xoadc_probe()
928 pm8xxx_eoc_irq, NULL, 0, variant->name, indio_dev); in pm8xxx_xoadc_probe()
934 indio_dev->name = variant->name; in pm8xxx_xoadc_probe()
935 indio_dev->modes = INDIO_DIRECT_MODE; in pm8xxx_xoadc_probe()
936 indio_dev->info = &pm8xxx_xoadc_info; in pm8xxx_xoadc_probe()
937 indio_dev->channels = adc->iio_chans; in pm8xxx_xoadc_probe()
938 indio_dev->num_channels = adc->nchans; in pm8xxx_xoadc_probe()
944 ret = pm8xxx_calibrate_device(adc); in pm8xxx_xoadc_probe()
948 dev_info(dev, "%s XOADC driver enabled\n", variant->name); in pm8xxx_xoadc_probe()
955 regulator_disable(adc->vref); in pm8xxx_xoadc_probe()
963 struct pm8xxx_xoadc *adc = iio_priv(indio_dev); in pm8xxx_xoadc_remove() local
967 regulator_disable(adc->vref); in pm8xxx_xoadc_remove()
973 .name = "PM8018-XOADC",
974 .channels = pm8018_xoadc_channels,
978 .name = "PM8038-XOADC",
979 .channels = pm8038_xoadc_channels,
983 .name = "PM8058-XOADC",
984 .channels = pm8058_xoadc_channels,
990 .name = "PM8921-XOADC",
991 .channels = pm8921_xoadc_channels,
997 .compatible = "qcom,pm8018-adc",
1001 .compatible = "qcom,pm8038-adc",
1005 .compatible = "qcom,pm8058-adc",
1009 .compatible = "qcom,pm8921-adc",
1018 .name = "pm8xxx-adc",
1028 MODULE_ALIAS("platform:pm8xxx-xoadc");