Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

iio: adc: vf610_adc: add helper function to read samples

This is a precursor change to make it simpler to remove the 'mlock'
usage. Having the code in it's own helper function, also makes it easier
to read the error paths.

Signed-off-by: Nuno Sá <nuno.sa@analog.com>
Reviewed-by: Haibo Chen <haibo.chen@nxp.com>
Link: https://lore.kernel.org/r/20221004134909.1692021-10-nuno.sa@analog.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Nuno Sá and committed by
Jonathan Cameron
f2bdea86 8433aa35

+54 -40
+54 -40
drivers/iio/adc/vf610_adc.c
··· 622 622 .attrs = vf610_attributes, 623 623 }; 624 624 625 + static int vf610_read_sample(struct iio_dev *indio_dev, 626 + struct iio_chan_spec const *chan, int *val) 627 + { 628 + struct vf610_adc *info = iio_priv(indio_dev); 629 + unsigned int hc_cfg; 630 + int ret; 631 + 632 + mutex_lock(&indio_dev->mlock); 633 + if (iio_buffer_enabled(indio_dev)) { 634 + ret = -EBUSY; 635 + goto out_unlock; 636 + } 637 + 638 + reinit_completion(&info->completion); 639 + hc_cfg = VF610_ADC_ADCHC(chan->channel); 640 + hc_cfg |= VF610_ADC_AIEN; 641 + writel(hc_cfg, info->regs + VF610_REG_ADC_HC0); 642 + ret = wait_for_completion_interruptible_timeout(&info->completion, 643 + VF610_ADC_TIMEOUT); 644 + if (ret == 0) { 645 + ret = -ETIMEDOUT; 646 + goto out_unlock; 647 + } 648 + 649 + if (ret < 0) 650 + goto out_unlock; 651 + 652 + switch (chan->type) { 653 + case IIO_VOLTAGE: 654 + *val = info->value; 655 + break; 656 + case IIO_TEMP: 657 + /* 658 + * Calculate in degree Celsius times 1000 659 + * Using the typical sensor slope of 1.84 mV/°C 660 + * and VREFH_ADC at 3.3V, V at 25°C of 699 mV 661 + */ 662 + *val = 25000 - ((int)info->value - VF610_VTEMP25_3V3) * 663 + 1000000 / VF610_TEMP_SLOPE_COEFF; 664 + 665 + break; 666 + default: 667 + ret = -EINVAL; 668 + break; 669 + } 670 + 671 + out_unlock: 672 + mutex_unlock(&indio_dev->mlock); 673 + 674 + return ret; 675 + } 676 + 625 677 static int vf610_read_raw(struct iio_dev *indio_dev, 626 678 struct iio_chan_spec const *chan, 627 679 int *val, ··· 681 629 long mask) 682 630 { 683 631 struct vf610_adc *info = iio_priv(indio_dev); 684 - unsigned int hc_cfg; 685 632 long ret; 686 633 687 634 switch (mask) { 688 635 case IIO_CHAN_INFO_RAW: 689 636 case IIO_CHAN_INFO_PROCESSED: 690 - mutex_lock(&indio_dev->mlock); 691 - if (iio_buffer_enabled(indio_dev)) { 692 - mutex_unlock(&indio_dev->mlock); 693 - return -EBUSY; 694 - } 695 - 696 - reinit_completion(&info->completion); 697 - hc_cfg = VF610_ADC_ADCHC(chan->channel); 698 - hc_cfg |= VF610_ADC_AIEN; 699 - writel(hc_cfg, info->regs + VF610_REG_ADC_HC0); 700 - ret = wait_for_completion_interruptible_timeout 701 - (&info->completion, VF610_ADC_TIMEOUT); 702 - if (ret == 0) { 703 - mutex_unlock(&indio_dev->mlock); 704 - return -ETIMEDOUT; 705 - } 706 - if (ret < 0) { 707 - mutex_unlock(&indio_dev->mlock); 637 + ret = vf610_read_sample(indio_dev, chan, val); 638 + if (ret < 0) 708 639 return ret; 709 - } 710 640 711 - switch (chan->type) { 712 - case IIO_VOLTAGE: 713 - *val = info->value; 714 - break; 715 - case IIO_TEMP: 716 - /* 717 - * Calculate in degree Celsius times 1000 718 - * Using the typical sensor slope of 1.84 mV/°C 719 - * and VREFH_ADC at 3.3V, V at 25°C of 699 mV 720 - */ 721 - *val = 25000 - ((int)info->value - VF610_VTEMP25_3V3) * 722 - 1000000 / VF610_TEMP_SLOPE_COEFF; 723 - 724 - break; 725 - default: 726 - mutex_unlock(&indio_dev->mlock); 727 - return -EINVAL; 728 - } 729 - 730 - mutex_unlock(&indio_dev->mlock); 731 641 return IIO_VAL_INT; 732 642 733 643 case IIO_CHAN_INFO_SCALE: