Message ID | 1481842105-14047-1-git-send-email-linus.walleij@linaro.org (mailing list archive) |
---|---|
State | Not Applicable, archived |
Delegated to: | Andy Gross |
Headers | show |
On 15/12/16 22:48, Linus Walleij wrote: > The SPMI VADC and the earlier XOADC share a subset of > common code, so to be able to use the same code in both > drivers, we break out a separate file with the common code, > prefix exported functions that are no longer static with > qcom_* and bake an object qcom-vadc.o that contains both > files: qcom-vadc-common.o and qcom-spmi-vadc.o. > > Cc: linux-arm-kernel@lists.infradead.org > Cc: linux-arm-msm@vger.kernel.org > Cc: Ivan T. Ivanov <iivanov.xz@gmail.com> > Cc: Andy Gross <andy.gross@linaro.org> > Cc: Bjorn Andersson <bjorn.andersson@linaro.org> > Cc: Stephen Boyd <sboyd@codeaurora.org> > Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> > Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Looks superficially fine, but I'm guessing will need a respin as we have a fair bit of new stuff (and a couple of fixes) going through this driver at the moment. All but the two fixes I posted a few mins ago are in my testing branch and should go to Greg once I have confirmed testing on those two fixes. Jonathan > --- > ChangeLog v1->v2: > - No changes just reposting > --- > drivers/iio/adc/Makefile | 3 +- > drivers/iio/adc/qcom-spmi-vadc.c | 95 +++----------------------------------- > drivers/iio/adc/qcom-vadc-common.c | 38 +++++++++++++++ > drivers/iio/adc/qcom-vadc-common.h | 69 +++++++++++++++++++++++++++ > 4 files changed, 116 insertions(+), 89 deletions(-) > create mode 100644 drivers/iio/adc/qcom-vadc-common.c > create mode 100644 drivers/iio/adc/qcom-vadc-common.h > > diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile > index 7a40c04c311f..f9468d228b1e 100644 > --- a/drivers/iio/adc/Makefile > +++ b/drivers/iio/adc/Makefile > @@ -38,7 +38,8 @@ obj-$(CONFIG_MXS_LRADC) += mxs-lradc.o > obj-$(CONFIG_NAU7802) += nau7802.o > obj-$(CONFIG_PALMAS_GPADC) += palmas_gpadc.o > obj-$(CONFIG_QCOM_SPMI_IADC) += qcom-spmi-iadc.o > -obj-$(CONFIG_QCOM_SPMI_VADC) += qcom-spmi-vadc.o > +qcom-vadc-y := qcom-vadc-common.o > +obj-$(CONFIG_QCOM_SPMI_VADC) += qcom-vadc.o qcom-spmi-vadc.o > obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o > obj-$(CONFIG_STX104) += stx104.o > obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o > diff --git a/drivers/iio/adc/qcom-spmi-vadc.c b/drivers/iio/adc/qcom-spmi-vadc.c > index c2babe50a0d8..74d21afa34a9 100644 > --- a/drivers/iio/adc/qcom-spmi-vadc.c > +++ b/drivers/iio/adc/qcom-spmi-vadc.c > @@ -28,6 +28,8 @@ > > #include <dt-bindings/iio/qcom,spmi-vadc.h> > > +#include "qcom-vadc-common.h" > + > /* VADC register and bit definitions */ > #define VADC_REVISION2 0x1 > #define VADC_REVISION2_SUPPORTED_VADC 1 > @@ -75,69 +77,9 @@ > > #define VADC_DATA 0x60 /* 16 bits */ > > -#define VADC_CONV_TIME_MIN_US 2000 > -#define VADC_CONV_TIME_MAX_US 2100 > - > -/* Min ADC code represents 0V */ > -#define VADC_MIN_ADC_CODE 0x6000 > -/* Max ADC code represents full-scale range of 1.8V */ > -#define VADC_MAX_ADC_CODE 0xa800 > - > -#define VADC_ABSOLUTE_RANGE_UV 625000 > -#define VADC_RATIOMETRIC_RANGE_UV 1800000 > - > -#define VADC_DEF_PRESCALING 0 /* 1:1 */ > -#define VADC_DEF_DECIMATION 0 /* 512 */ > -#define VADC_DEF_HW_SETTLE_TIME 0 /* 0 us */ > -#define VADC_DEF_AVG_SAMPLES 0 /* 1 sample */ > -#define VADC_DEF_CALIB_TYPE VADC_CALIB_ABSOLUTE > - > -#define VADC_DECIMATION_MIN 512 > -#define VADC_DECIMATION_MAX 4096 > - > -#define VADC_HW_SETTLE_DELAY_MAX 10000 > -#define VADC_AVG_SAMPLES_MAX 512 > - > -#define KELVINMIL_CELSIUSMIL 273150 > - > #define VADC_CHAN_MIN VADC_USBIN > #define VADC_CHAN_MAX VADC_LR_MUX3_BUF_PU1_PU2_XO_THERM > > -/* > - * VADC_CALIB_ABSOLUTE: uses the 625mV and 1.25V as reference channels. > - * VADC_CALIB_RATIOMETRIC: uses the reference voltage (1.8V) and GND for > - * calibration. > - */ > -enum vadc_calibration { > - VADC_CALIB_ABSOLUTE = 0, > - VADC_CALIB_RATIOMETRIC > -}; > - > -/** > - * struct vadc_linear_graph - Represent ADC characteristics. > - * @dy: numerator slope to calculate the gain. > - * @dx: denominator slope to calculate the gain. > - * @gnd: A/D word of the ground reference used for the channel. > - * > - * Each ADC device has different offset and gain parameters which are > - * computed to calibrate the device. > - */ > -struct vadc_linear_graph { > - s32 dy; > - s32 dx; > - s32 gnd; > -}; > - > -/** > - * struct vadc_prescale_ratio - Represent scaling ratio for ADC input. > - * @num: the inverse numerator of the gain applied to the input channel. > - * @den: the inverse denominator of the gain applied to the input channel. > - */ > -struct vadc_prescale_ratio { > - u32 num; > - u32 den; > -}; > - > /** > * struct vadc_channel_prop - VADC channel property. > * @channel: channel number, refer to the channel list. > @@ -471,33 +413,10 @@ static int vadc_measure_ref_points(struct vadc_priv *vadc) > static s32 vadc_calibrate(struct vadc_priv *vadc, > const struct vadc_channel_prop *prop, u16 adc_code) > { > - const struct vadc_prescale_ratio *prescale; > - s64 voltage; > - > - voltage = adc_code - vadc->graph[prop->calibration].gnd; > - voltage *= vadc->graph[prop->calibration].dx; > - voltage = div64_s64(voltage, vadc->graph[prop->calibration].dy); > - > - if (prop->calibration == VADC_CALIB_ABSOLUTE) > - voltage += vadc->graph[prop->calibration].dx; > - > - if (voltage < 0) > - voltage = 0; > - > - prescale = &vadc_prescale_ratios[prop->prescale]; > - > - voltage = voltage * prescale->den; > - > - return div64_s64(voltage, prescale->num); > -} > - > -static int vadc_decimation_from_dt(u32 value) > -{ > - if (!is_power_of_2(value) || value < VADC_DECIMATION_MIN || > - value > VADC_DECIMATION_MAX) > - return -EINVAL; > - > - return __ffs64(value / VADC_DECIMATION_MIN); > + return qcom_vadc_calibrate(&vadc_prescale_ratios[prop->prescale], > + &vadc->graph[prop->calibration], > + (prop->calibration == VADC_CALIB_ABSOLUTE), > + adc_code); > } > > static int vadc_prescaling_from_dt(u32 num, u32 den) > @@ -752,7 +671,7 @@ static int vadc_get_dt_channel_data(struct device *dev, > > ret = of_property_read_u32(node, "qcom,decimation", &value); > if (!ret) { > - ret = vadc_decimation_from_dt(value); > + ret = qcom_vadc_decimation_from_dt(value); > if (ret < 0) { > dev_err(dev, "%02x invalid decimation %d\n", > chan, value); > diff --git a/drivers/iio/adc/qcom-vadc-common.c b/drivers/iio/adc/qcom-vadc-common.c > new file mode 100644 > index 000000000000..f67fc5e2a702 > --- /dev/null > +++ b/drivers/iio/adc/qcom-vadc-common.c > @@ -0,0 +1,38 @@ > +#include <linux/kernel.h> > +#include <linux/bitops.h> > +#include <linux/math64.h> > +#include <linux/log2.h> > +#include <linux/err.h> > + > +#include "qcom-vadc-common.h" > + > +s32 qcom_vadc_calibrate(const struct vadc_prescale_ratio *prescale, > + const struct vadc_linear_graph *graph, > + bool absolute, > + u16 adc_code) > +{ > + s64 voltage; > + > + voltage = adc_code - graph->gnd; > + voltage *= graph->dx; > + voltage = div64_s64(voltage, graph->dy); > + > + if (absolute) > + voltage += graph->dx; > + > + if (voltage < 0) > + voltage = 0; > + > + voltage = voltage * prescale->den; > + > + return div64_s64(voltage, prescale->num); > +} > + > +int qcom_vadc_decimation_from_dt(u32 value) > +{ > + if (!is_power_of_2(value) || value < VADC_DECIMATION_MIN || > + value > VADC_DECIMATION_MAX) > + return -EINVAL; > + > + return __ffs64(value / VADC_DECIMATION_MIN); > +} > diff --git a/drivers/iio/adc/qcom-vadc-common.h b/drivers/iio/adc/qcom-vadc-common.h > new file mode 100644 > index 000000000000..b41cb501eef8 > --- /dev/null > +++ b/drivers/iio/adc/qcom-vadc-common.h > @@ -0,0 +1,69 @@ > +/* > + * Code shared between the different Qualcomm PMIC voltage ADCs > + */ > + > +#define VADC_CONV_TIME_MIN_US 2000 > +#define VADC_CONV_TIME_MAX_US 2100 > + > +/* Min ADC code represents 0V */ > +#define VADC_MIN_ADC_CODE 0x6000 > +/* Max ADC code represents full-scale range of 1.8V */ > +#define VADC_MAX_ADC_CODE 0xa800 > + > +#define VADC_ABSOLUTE_RANGE_UV 625000 > +#define VADC_RATIOMETRIC_RANGE_UV 1800000 > + > +#define VADC_DEF_PRESCALING 0 /* 1:1 */ > +#define VADC_DEF_DECIMATION 0 /* 512 */ > +#define VADC_DEF_HW_SETTLE_TIME 0 /* 0 us */ > +#define VADC_DEF_AVG_SAMPLES 0 /* 1 sample */ > +#define VADC_DEF_CALIB_TYPE VADC_CALIB_ABSOLUTE > + > +#define VADC_DECIMATION_MIN 512 > +#define VADC_DECIMATION_MAX 4096 > + > +#define VADC_HW_SETTLE_DELAY_MAX 10000 > +#define VADC_AVG_SAMPLES_MAX 512 > + > +#define KELVINMIL_CELSIUSMIL 273150 > + > +/* > + * VADC_CALIB_ABSOLUTE: uses the 625mV and 1.25V as reference channels. > + * VADC_CALIB_RATIOMETRIC: uses the reference voltage (1.8V) and GND for > + * calibration. > + */ > +enum vadc_calibration { > + VADC_CALIB_ABSOLUTE = 0, > + VADC_CALIB_RATIOMETRIC > +}; > + > +/** > + * struct vadc_linear_graph - Represent ADC characteristics. > + * @dy: numerator slope to calculate the gain. > + * @dx: denominator slope to calculate the gain. > + * @gnd: A/D word of the ground reference used for the channel. > + * > + * Each ADC device has different offset and gain parameters which are > + * computed to calibrate the device. > + */ > +struct vadc_linear_graph { > + s32 dy; > + s32 dx; > + s32 gnd; > +}; > + > +/** > + * struct vadc_prescale_ratio - Represent scaling ratio for ADC input. > + * @num: the inverse numerator of the gain applied to the input channel. > + * @den: the inverse denominator of the gain applied to the input channel. > + */ > +struct vadc_prescale_ratio { > + u32 num; > + u32 den; > +}; > + > +s32 qcom_vadc_calibrate(const struct vadc_prescale_ratio *prescale, > + const struct vadc_linear_graph *graph, > + bool absolute, > + u16 adc_code); > +int qcom_vadc_decimation_from_dt(u32 value); > -- To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Fri, Dec 30, 2016 at 8:01 PM, Jonathan Cameron <jic23@kernel.org> wrote: > On 15/12/16 22:48, Linus Walleij wrote: >> The SPMI VADC and the earlier XOADC share a subset of >> common code, so to be able to use the same code in both >> drivers, we break out a separate file with the common code, >> prefix exported functions that are no longer static with >> qcom_* and bake an object qcom-vadc.o that contains both >> files: qcom-vadc-common.o and qcom-spmi-vadc.o. >> >> Cc: linux-arm-kernel@lists.infradead.org >> Cc: linux-arm-msm@vger.kernel.org >> Cc: Ivan T. Ivanov <iivanov.xz@gmail.com> >> Cc: Andy Gross <andy.gross@linaro.org> >> Cc: Bjorn Andersson <bjorn.andersson@linaro.org> >> Cc: Stephen Boyd <sboyd@codeaurora.org> >> Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> >> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> > > Looks superficially fine, but I'm guessing will need a respin > as we have a fair bit of new stuff (and a couple of fixes) going > through this driver at the moment. > > All but the two fixes I posted a few mins ago are in my testing > branch and should go to Greg once I have confirmed testing on > those two fixes. I looked at the git and "testing" contains a top commit named "guessing" fixing some 64bit artithmetic (which looks correct) in the driver, shall I simply rebase on top of that and hope for the best? :) Yours, Linus Walleij -- To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 10.01.2017 08:54, Linus Walleij wrote: > On Fri, Dec 30, 2016 at 8:01 PM, Jonathan Cameron <jic23@kernel.org> > wrote: >> On 15/12/16 22:48, Linus Walleij wrote: >>> The SPMI VADC and the earlier XOADC share a subset of >>> common code, so to be able to use the same code in both >>> drivers, we break out a separate file with the common code, >>> prefix exported functions that are no longer static with >>> qcom_* and bake an object qcom-vadc.o that contains both >>> files: qcom-vadc-common.o and qcom-spmi-vadc.o. >>> >>> Cc: linux-arm-kernel@lists.infradead.org >>> Cc: linux-arm-msm@vger.kernel.org >>> Cc: Ivan T. Ivanov <iivanov.xz@gmail.com> >>> Cc: Andy Gross <andy.gross@linaro.org> >>> Cc: Bjorn Andersson <bjorn.andersson@linaro.org> >>> Cc: Stephen Boyd <sboyd@codeaurora.org> >>> Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> >>> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> >> >> Looks superficially fine, but I'm guessing will need a respin >> as we have a fair bit of new stuff (and a couple of fixes) going >> through this driver at the moment. >> >> All but the two fixes I posted a few mins ago are in my testing >> branch and should go to Greg once I have confirmed testing on >> those two fixes. > > I looked at the git and "testing" > contains a top commit named "guessing" fixing some 64bit > artithmetic (which looks correct) in the driver, shall I simply > rebase on top of that and hope for the best? :) I'm an idiot and pushed out the wrong branch. Will fix up when I get home and push one with a sensible patch title! (It'll be the same content though - feel free to Ack that if you like ;) Not my best half asleep patch writing ;) Jonathan > > Yours, > Linus Walleij > -- > To unsubscribe from this list: send the line "unsubscribe linux-iio" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 10/01/17 14:21, jic23@kernel.org wrote: > On 10.01.2017 08:54, Linus Walleij wrote: >> On Fri, Dec 30, 2016 at 8:01 PM, Jonathan Cameron <jic23@kernel.org> wrote: >>> On 15/12/16 22:48, Linus Walleij wrote: >>>> The SPMI VADC and the earlier XOADC share a subset of >>>> common code, so to be able to use the same code in both >>>> drivers, we break out a separate file with the common code, >>>> prefix exported functions that are no longer static with >>>> qcom_* and bake an object qcom-vadc.o that contains both >>>> files: qcom-vadc-common.o and qcom-spmi-vadc.o. >>>> >>>> Cc: linux-arm-kernel@lists.infradead.org >>>> Cc: linux-arm-msm@vger.kernel.org >>>> Cc: Ivan T. Ivanov <iivanov.xz@gmail.com> >>>> Cc: Andy Gross <andy.gross@linaro.org> >>>> Cc: Bjorn Andersson <bjorn.andersson@linaro.org> >>>> Cc: Stephen Boyd <sboyd@codeaurora.org> >>>> Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> >>>> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> >>> >>> Looks superficially fine, but I'm guessing will need a respin >>> as we have a fair bit of new stuff (and a couple of fixes) going >>> through this driver at the moment. >>> >>> All but the two fixes I posted a few mins ago are in my testing >>> branch and should go to Greg once I have confirmed testing on >>> those two fixes. >> >> I looked at the git and "testing" >> contains a top commit named "guessing" fixing some 64bit >> artithmetic (which looks correct) in the driver, shall I simply >> rebase on top of that and hope for the best? :) > I'm an idiot and pushed out the wrong branch. Will fix up when > I get home and push one with a sensible patch title! > (It'll be the same content though - feel free to Ack that if > you like ;) > > Not my best half asleep patch writing ;) Fixed... It's called testing for a reason ;) Jonathan > > Jonathan >> >> Yours, >> Linus Walleij >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-iio" in >> the body of a message to majordomo@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html > -- > To unsubscribe from this list: send the line "unsubscribe linux-iio" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 7a40c04c311f..f9468d228b1e 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -38,7 +38,8 @@ obj-$(CONFIG_MXS_LRADC) += mxs-lradc.o obj-$(CONFIG_NAU7802) += nau7802.o obj-$(CONFIG_PALMAS_GPADC) += palmas_gpadc.o obj-$(CONFIG_QCOM_SPMI_IADC) += qcom-spmi-iadc.o -obj-$(CONFIG_QCOM_SPMI_VADC) += qcom-spmi-vadc.o +qcom-vadc-y := qcom-vadc-common.o +obj-$(CONFIG_QCOM_SPMI_VADC) += qcom-vadc.o qcom-spmi-vadc.o obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o obj-$(CONFIG_STX104) += stx104.o obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o diff --git a/drivers/iio/adc/qcom-spmi-vadc.c b/drivers/iio/adc/qcom-spmi-vadc.c index c2babe50a0d8..74d21afa34a9 100644 --- a/drivers/iio/adc/qcom-spmi-vadc.c +++ b/drivers/iio/adc/qcom-spmi-vadc.c @@ -28,6 +28,8 @@ #include <dt-bindings/iio/qcom,spmi-vadc.h> +#include "qcom-vadc-common.h" + /* VADC register and bit definitions */ #define VADC_REVISION2 0x1 #define VADC_REVISION2_SUPPORTED_VADC 1 @@ -75,69 +77,9 @@ #define VADC_DATA 0x60 /* 16 bits */ -#define VADC_CONV_TIME_MIN_US 2000 -#define VADC_CONV_TIME_MAX_US 2100 - -/* Min ADC code represents 0V */ -#define VADC_MIN_ADC_CODE 0x6000 -/* Max ADC code represents full-scale range of 1.8V */ -#define VADC_MAX_ADC_CODE 0xa800 - -#define VADC_ABSOLUTE_RANGE_UV 625000 -#define VADC_RATIOMETRIC_RANGE_UV 1800000 - -#define VADC_DEF_PRESCALING 0 /* 1:1 */ -#define VADC_DEF_DECIMATION 0 /* 512 */ -#define VADC_DEF_HW_SETTLE_TIME 0 /* 0 us */ -#define VADC_DEF_AVG_SAMPLES 0 /* 1 sample */ -#define VADC_DEF_CALIB_TYPE VADC_CALIB_ABSOLUTE - -#define VADC_DECIMATION_MIN 512 -#define VADC_DECIMATION_MAX 4096 - -#define VADC_HW_SETTLE_DELAY_MAX 10000 -#define VADC_AVG_SAMPLES_MAX 512 - -#define KELVINMIL_CELSIUSMIL 273150 - #define VADC_CHAN_MIN VADC_USBIN #define VADC_CHAN_MAX VADC_LR_MUX3_BUF_PU1_PU2_XO_THERM -/* - * VADC_CALIB_ABSOLUTE: uses the 625mV and 1.25V as reference channels. - * VADC_CALIB_RATIOMETRIC: uses the reference voltage (1.8V) and GND for - * calibration. - */ -enum vadc_calibration { - VADC_CALIB_ABSOLUTE = 0, - VADC_CALIB_RATIOMETRIC -}; - -/** - * struct vadc_linear_graph - Represent ADC characteristics. - * @dy: numerator slope to calculate the gain. - * @dx: denominator slope to calculate the gain. - * @gnd: A/D word of the ground reference used for the channel. - * - * Each ADC device has different offset and gain parameters which are - * computed to calibrate the device. - */ -struct vadc_linear_graph { - s32 dy; - s32 dx; - s32 gnd; -}; - -/** - * struct vadc_prescale_ratio - Represent scaling ratio for ADC input. - * @num: the inverse numerator of the gain applied to the input channel. - * @den: the inverse denominator of the gain applied to the input channel. - */ -struct vadc_prescale_ratio { - u32 num; - u32 den; -}; - /** * struct vadc_channel_prop - VADC channel property. * @channel: channel number, refer to the channel list. @@ -471,33 +413,10 @@ static int vadc_measure_ref_points(struct vadc_priv *vadc) static s32 vadc_calibrate(struct vadc_priv *vadc, const struct vadc_channel_prop *prop, u16 adc_code) { - const struct vadc_prescale_ratio *prescale; - s64 voltage; - - voltage = adc_code - vadc->graph[prop->calibration].gnd; - voltage *= vadc->graph[prop->calibration].dx; - voltage = div64_s64(voltage, vadc->graph[prop->calibration].dy); - - if (prop->calibration == VADC_CALIB_ABSOLUTE) - voltage += vadc->graph[prop->calibration].dx; - - if (voltage < 0) - voltage = 0; - - prescale = &vadc_prescale_ratios[prop->prescale]; - - voltage = voltage * prescale->den; - - return div64_s64(voltage, prescale->num); -} - -static int vadc_decimation_from_dt(u32 value) -{ - if (!is_power_of_2(value) || value < VADC_DECIMATION_MIN || - value > VADC_DECIMATION_MAX) - return -EINVAL; - - return __ffs64(value / VADC_DECIMATION_MIN); + return qcom_vadc_calibrate(&vadc_prescale_ratios[prop->prescale], + &vadc->graph[prop->calibration], + (prop->calibration == VADC_CALIB_ABSOLUTE), + adc_code); } static int vadc_prescaling_from_dt(u32 num, u32 den) @@ -752,7 +671,7 @@ static int vadc_get_dt_channel_data(struct device *dev, ret = of_property_read_u32(node, "qcom,decimation", &value); if (!ret) { - ret = vadc_decimation_from_dt(value); + ret = qcom_vadc_decimation_from_dt(value); if (ret < 0) { dev_err(dev, "%02x invalid decimation %d\n", chan, value); diff --git a/drivers/iio/adc/qcom-vadc-common.c b/drivers/iio/adc/qcom-vadc-common.c new file mode 100644 index 000000000000..f67fc5e2a702 --- /dev/null +++ b/drivers/iio/adc/qcom-vadc-common.c @@ -0,0 +1,38 @@ +#include <linux/kernel.h> +#include <linux/bitops.h> +#include <linux/math64.h> +#include <linux/log2.h> +#include <linux/err.h> + +#include "qcom-vadc-common.h" + +s32 qcom_vadc_calibrate(const struct vadc_prescale_ratio *prescale, + const struct vadc_linear_graph *graph, + bool absolute, + u16 adc_code) +{ + s64 voltage; + + voltage = adc_code - graph->gnd; + voltage *= graph->dx; + voltage = div64_s64(voltage, graph->dy); + + if (absolute) + voltage += graph->dx; + + if (voltage < 0) + voltage = 0; + + voltage = voltage * prescale->den; + + return div64_s64(voltage, prescale->num); +} + +int qcom_vadc_decimation_from_dt(u32 value) +{ + if (!is_power_of_2(value) || value < VADC_DECIMATION_MIN || + value > VADC_DECIMATION_MAX) + return -EINVAL; + + return __ffs64(value / VADC_DECIMATION_MIN); +} diff --git a/drivers/iio/adc/qcom-vadc-common.h b/drivers/iio/adc/qcom-vadc-common.h new file mode 100644 index 000000000000..b41cb501eef8 --- /dev/null +++ b/drivers/iio/adc/qcom-vadc-common.h @@ -0,0 +1,69 @@ +/* + * Code shared between the different Qualcomm PMIC voltage ADCs + */ + +#define VADC_CONV_TIME_MIN_US 2000 +#define VADC_CONV_TIME_MAX_US 2100 + +/* Min ADC code represents 0V */ +#define VADC_MIN_ADC_CODE 0x6000 +/* Max ADC code represents full-scale range of 1.8V */ +#define VADC_MAX_ADC_CODE 0xa800 + +#define VADC_ABSOLUTE_RANGE_UV 625000 +#define VADC_RATIOMETRIC_RANGE_UV 1800000 + +#define VADC_DEF_PRESCALING 0 /* 1:1 */ +#define VADC_DEF_DECIMATION 0 /* 512 */ +#define VADC_DEF_HW_SETTLE_TIME 0 /* 0 us */ +#define VADC_DEF_AVG_SAMPLES 0 /* 1 sample */ +#define VADC_DEF_CALIB_TYPE VADC_CALIB_ABSOLUTE + +#define VADC_DECIMATION_MIN 512 +#define VADC_DECIMATION_MAX 4096 + +#define VADC_HW_SETTLE_DELAY_MAX 10000 +#define VADC_AVG_SAMPLES_MAX 512 + +#define KELVINMIL_CELSIUSMIL 273150 + +/* + * VADC_CALIB_ABSOLUTE: uses the 625mV and 1.25V as reference channels. + * VADC_CALIB_RATIOMETRIC: uses the reference voltage (1.8V) and GND for + * calibration. + */ +enum vadc_calibration { + VADC_CALIB_ABSOLUTE = 0, + VADC_CALIB_RATIOMETRIC +}; + +/** + * struct vadc_linear_graph - Represent ADC characteristics. + * @dy: numerator slope to calculate the gain. + * @dx: denominator slope to calculate the gain. + * @gnd: A/D word of the ground reference used for the channel. + * + * Each ADC device has different offset and gain parameters which are + * computed to calibrate the device. + */ +struct vadc_linear_graph { + s32 dy; + s32 dx; + s32 gnd; +}; + +/** + * struct vadc_prescale_ratio - Represent scaling ratio for ADC input. + * @num: the inverse numerator of the gain applied to the input channel. + * @den: the inverse denominator of the gain applied to the input channel. + */ +struct vadc_prescale_ratio { + u32 num; + u32 den; +}; + +s32 qcom_vadc_calibrate(const struct vadc_prescale_ratio *prescale, + const struct vadc_linear_graph *graph, + bool absolute, + u16 adc_code); +int qcom_vadc_decimation_from_dt(u32 value);
The SPMI VADC and the earlier XOADC share a subset of common code, so to be able to use the same code in both drivers, we break out a separate file with the common code, prefix exported functions that are no longer static with qcom_* and bake an object qcom-vadc.o that contains both files: qcom-vadc-common.o and qcom-spmi-vadc.o. Cc: linux-arm-kernel@lists.infradead.org Cc: linux-arm-msm@vger.kernel.org Cc: Ivan T. Ivanov <iivanov.xz@gmail.com> Cc: Andy Gross <andy.gross@linaro.org> Cc: Bjorn Andersson <bjorn.andersson@linaro.org> Cc: Stephen Boyd <sboyd@codeaurora.org> Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- ChangeLog v1->v2: - No changes just reposting --- drivers/iio/adc/Makefile | 3 +- drivers/iio/adc/qcom-spmi-vadc.c | 95 +++----------------------------------- drivers/iio/adc/qcom-vadc-common.c | 38 +++++++++++++++ drivers/iio/adc/qcom-vadc-common.h | 69 +++++++++++++++++++++++++++ 4 files changed, 116 insertions(+), 89 deletions(-) create mode 100644 drivers/iio/adc/qcom-vadc-common.c create mode 100644 drivers/iio/adc/qcom-vadc-common.h