// SPDX-License-Identifier: GPL-2.0-only /* * Qualcomm PM8xxx PMIC XOADC driver * * These ADCs are known as HK/XO (house keeping / chrystal oscillator) * "XO" in "XOADC" means Chrystal Oscillator. It's a bunch of * specific-purpose and general purpose ADC converters and channels. * * Copyright (C) 2017 Linaro Ltd. * Author: Linus Walleij <[email protected]> */ #include <linux/iio/adc/qcom-vadc-common.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> #include <linux/module.h> #include <linux/mod_devicetable.h> #include <linux/platform_device.h> #include <linux/property.h> #include <linux/regmap.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/regulator/consumer.h> /* * Definitions for the "user processor" registers lifted from the v3.4 * Qualcomm tree. Their kernel has two out-of-tree drivers for the ADC: * drivers/misc/pmic8058-xoadc.c * drivers/hwmon/pm8xxx-adc.c * None of them contain any complete register specification, so this is * a best effort of combining the information. */ /* These appear to be "battery monitor" registers */ #define ADC_ARB_BTM_CNTRL1 … #define ADC_ARB_BTM_CNTRL1_EN_BTM … #define ADC_ARB_BTM_CNTRL1_SEL_OP_MODE … #define ADC_ARB_BTM_CNTRL1_MEAS_INTERVAL1 … #define ADC_ARB_BTM_CNTRL1_MEAS_INTERVAL2 … #define ADC_ARB_BTM_CNTRL1_MEAS_INTERVAL3 … #define ADC_ARB_BTM_CNTRL1_MEAS_INTERVAL4 … #define ADC_ARB_BTM_CNTRL1_EOC … #define ADC_ARB_BTM_CNTRL1_REQ … #define ADC_ARB_BTM_AMUX_CNTRL … #define ADC_ARB_BTM_ANA_PARAM … #define ADC_ARB_BTM_DIG_PARAM … #define ADC_ARB_BTM_RSV … #define ADC_ARB_BTM_DATA1 … #define ADC_ARB_BTM_DATA0 … #define ADC_ARB_BTM_BAT_COOL_THR1 … #define ADC_ARB_BTM_BAT_COOL_THR0 … #define ADC_ARB_BTM_BAT_WARM_THR1 … #define ADC_ARB_BTM_BAT_WARM_THR0 … #define ADC_ARB_BTM_CNTRL2 … /* Proper ADC registers */ #define ADC_ARB_USRP_CNTRL … #define ADC_ARB_USRP_CNTRL_EN_ARB … #define ADC_ARB_USRP_CNTRL_RSV1 … #define ADC_ARB_USRP_CNTRL_RSV2 … #define ADC_ARB_USRP_CNTRL_RSV3 … #define ADC_ARB_USRP_CNTRL_RSV4 … #define ADC_ARB_USRP_CNTRL_RSV5 … #define ADC_ARB_USRP_CNTRL_EOC … #define ADC_ARB_USRP_CNTRL_REQ … #define ADC_ARB_USRP_AMUX_CNTRL … /* * The channel mask includes the bits selecting channel mux and prescaler * on PM8058, or channel mux and premux on PM8921. */ #define ADC_ARB_USRP_AMUX_CNTRL_CHAN_MASK … #define ADC_ARB_USRP_AMUX_CNTRL_RSV0 … #define ADC_ARB_USRP_AMUX_CNTRL_RSV1 … /* On PM8058 this is prescaling, on PM8921 this is premux */ #define ADC_ARB_USRP_AMUX_CNTRL_PRESCALEMUX0 … #define ADC_ARB_USRP_AMUX_CNTRL_PRESCALEMUX1 … #define ADC_ARB_USRP_AMUX_CNTRL_SEL0 … #define ADC_ARB_USRP_AMUX_CNTRL_SEL1 … #define ADC_ARB_USRP_AMUX_CNTRL_SEL2 … #define ADC_ARB_USRP_AMUX_CNTRL_SEL3 … #define ADC_AMUX_PREMUX_SHIFT … #define ADC_AMUX_SEL_SHIFT … /* We know very little about the bits in this register */ #define ADC_ARB_USRP_ANA_PARAM … #define ADC_ARB_USRP_ANA_PARAM_DIS … #define ADC_ARB_USRP_ANA_PARAM_EN … #define ADC_ARB_USRP_DIG_PARAM … #define ADC_ARB_USRP_DIG_PARAM_SEL_SHIFT0 … #define ADC_ARB_USRP_DIG_PARAM_SEL_SHIFT1 … #define ADC_ARB_USRP_DIG_PARAM_CLK_RATE0 … #define ADC_ARB_USRP_DIG_PARAM_CLK_RATE1 … #define ADC_ARB_USRP_DIG_PARAM_EOC … /* * On a later ADC the decimation factors are defined as * 00 = 512, 01 = 1024, 10 = 2048, 11 = 4096 so assume this * holds also for this older XOADC. */ #define ADC_ARB_USRP_DIG_PARAM_DEC_RATE0 … #define ADC_ARB_USRP_DIG_PARAM_DEC_RATE1 … #define ADC_ARB_USRP_DIG_PARAM_EN … #define ADC_DIG_PARAM_DEC_SHIFT … #define ADC_ARB_USRP_RSV … #define ADC_ARB_USRP_RSV_RST … #define ADC_ARB_USRP_RSV_DTEST0 … #define ADC_ARB_USRP_RSV_DTEST1 … #define ADC_ARB_USRP_RSV_OP … #define ADC_ARB_USRP_RSV_IP_SEL0 … #define ADC_ARB_USRP_RSV_IP_SEL1 … #define ADC_ARB_USRP_RSV_IP_SEL2 … #define ADC_ARB_USRP_RSV_TRM … #define ADC_RSV_IP_SEL_SHIFT … #define ADC_ARB_USRP_DATA0 … #define ADC_ARB_USRP_DATA1 … /* * Physical channels which MUST exist on all PM variants in order to provide * proper reference points for calibration. * * @PM8XXX_CHANNEL_INTERNAL: 625mV reference channel * @PM8XXX_CHANNEL_125V: 1250mV reference channel * @PM8XXX_CHANNEL_INTERNAL_2: 325mV reference channel * @PM8XXX_CHANNEL_MUXOFF: channel to reduce input load on mux, apparently also * measures XO temperature */ #define PM8XXX_CHANNEL_INTERNAL … #define PM8XXX_CHANNEL_125V … #define PM8XXX_CHANNEL_INTERNAL_2 … #define PM8XXX_CHANNEL_MUXOFF … /* * PM8058 AMUX premux scaling, two bits. This is done of the channel before * reaching the AMUX. */ #define PM8058_AMUX_PRESCALE_0 … #define PM8058_AMUX_PRESCALE_1 … #define PM8058_AMUX_PRESCALE_1_DIV3 … /* Defines reference voltage for the XOADC */ #define AMUX_RSV0 … #define AMUX_RSV1 … #define AMUX_RSV2 … #define AMUX_RSV3 … #define AMUX_RSV4 … #define AMUX_RSV5 … #define XOADC_RSV_MAX … /** * struct xoadc_channel - encodes channel properties and defaults * @datasheet_name: the hardwarename of this channel * @pre_scale_mux: prescale (PM8058) or premux (PM8921) for selecting * this channel. Both this and the amux channel is needed to uniquely * identify a channel. Values 0..3. * @amux_channel: value of the ADC_ARB_USRP_AMUX_CNTRL register for this * channel, bits 4..7, selects the amux, values 0..f * @prescale: the channels have hard-coded prescale ratios defined * by the hardware, this tells us what it is * @type: corresponding IIO channel type, usually IIO_VOLTAGE or * IIO_TEMP * @scale_fn_type: the liner interpolation etc to convert the * ADC code to the value that IIO expects, in uV or millicelsius * etc. This scale function can be pretty elaborate if different * thermistors are connected or other hardware characteristics are * deployed. * @amux_ip_rsv: ratiometric scale value used by the analog muxer: this * selects the reference voltage for ratiometric scaling */ struct xoadc_channel { … }; /** * struct xoadc_variant - encodes the XOADC variant characteristics * @name: name of this PMIC variant * @channels: the hardware channels and respective settings and defaults * @broken_ratiometric: if the PMIC has broken ratiometric scaling (this * is a known problem on PM8058) * @prescaling: this variant uses AMUX bits 2 & 3 for prescaling (PM8058) * @second_level_mux: this variant uses AMUX bits 2 & 3 for a second level * mux */ struct xoadc_variant { … }; /* * XOADC_CHAN macro parameters: * _dname: the name of the channel * _presmux: prescaler (PM8058) or premux (PM8921) setting for this channel * _amux: the value in bits 2..7 of the ADC_ARB_USRP_AMUX_CNTRL register * for this channel. On some PMICs some of the bits select a prescaler, and * on some PMICs some of the bits select various complex multiplex settings. * _type: IIO channel type * _prenum: prescaler numerator (dividend) * _preden: prescaler denominator (divisor) * _scale: scaling function type, this selects how the raw valued is mangled * to output the actual processed measurement * _amip: analog mux input parent when using ratiometric measurements */ #define XOADC_CHAN(_dname, _presmux, _amux, _type, _prenum, _preden, _scale, _amip) … /* * Taken from arch/arm/mach-msm/board-9615.c in the vendor tree: * TODO: incomplete, needs testing. */ static const struct xoadc_channel pm8018_xoadc_channels[] = …; /* * Taken from arch/arm/mach-msm/board-8930-pmic.c in the vendor tree: * TODO: needs testing. */ static const struct xoadc_channel pm8038_xoadc_channels[] = …; /* * This was created by cross-referencing the vendor tree * arch/arm/mach-msm/board-msm8x60.c msm_adc_channels_data[] * with the "channel types" (first field) to find the right * configuration for these channels on an MSM8x60 i.e. PM8058 * setup. */ static const struct xoadc_channel pm8058_xoadc_channels[] = …; /* * The PM8921 has some pre-muxing on its channels, this comes from the vendor tree * include/linux/mfd/pm8xxx/pm8xxx-adc.h * board-flo-pmic.c (Nexus 7) and board-8064-pmic.c */ static const struct xoadc_channel pm8921_xoadc_channels[] = …; /** * struct pm8xxx_chan_info - ADC channel information * @name: name of this channel * @hwchan: pointer to hardware channel information (muxing & scaling settings) * @calibration: whether to use absolute or ratiometric calibration * @decimation: 0,1,2,3 * @amux_ip_rsv: ratiometric scale value if using ratiometric * calibration: 0, 1, 2, 4, 5. */ struct pm8xxx_chan_info { … }; /** * struct pm8xxx_xoadc - state container for the XOADC * @dev: pointer to device * @map: regmap to access registers * @variant: XOADC variant characteristics * @vref: reference voltage regulator * characteristics of the channels, and sensible default settings * @nchans: number of channels, configured by the device tree * @chans: the channel information per-channel, configured by the device tree * @iio_chans: IIO channel specifiers * @graph: linear calibration parameters for absolute and * ratiometric measurements * @complete: completion to indicate end of conversion * @lock: lock to restrict access to the hardware to one client at the time */ struct pm8xxx_xoadc { … }; static irqreturn_t pm8xxx_eoc_irq(int irq, void *d) { … } static struct pm8xxx_chan_info * pm8xxx_get_channel(struct pm8xxx_xoadc *adc, u8 chan) { … } static int pm8xxx_read_channel_rsv(struct pm8xxx_xoadc *adc, const struct pm8xxx_chan_info *ch, u8 rsv, u16 *adc_code, bool force_ratiometric) { … } static int pm8xxx_read_channel(struct pm8xxx_xoadc *adc, const struct pm8xxx_chan_info *ch, u16 *adc_code) { … } static int pm8xxx_calibrate_device(struct pm8xxx_xoadc *adc) { … } static int pm8xxx_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) { … } static int pm8xxx_fwnode_xlate(struct iio_dev *indio_dev, const struct fwnode_reference_args *iiospec) { … } static const struct iio_info pm8xxx_xoadc_info = …; static int pm8xxx_xoadc_parse_channel(struct device *dev, struct fwnode_handle *fwnode, const struct xoadc_channel *hw_channels, struct iio_chan_spec *iio_chan, struct pm8xxx_chan_info *ch) { … } static int pm8xxx_xoadc_parse_channels(struct pm8xxx_xoadc *adc) { … } static int pm8xxx_xoadc_probe(struct platform_device *pdev) { … } static void pm8xxx_xoadc_remove(struct platform_device *pdev) { … } static const struct xoadc_variant pm8018_variant = …; static const struct xoadc_variant pm8038_variant = …; static const struct xoadc_variant pm8058_variant = …; static const struct xoadc_variant pm8921_variant = …; static const struct of_device_id pm8xxx_xoadc_id_table[] = …; MODULE_DEVICE_TABLE(of, pm8xxx_xoadc_id_table); static struct platform_driver pm8xxx_xoadc_driver = …; module_platform_driver(…) …; MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …; MODULE_ALIAS(…) …;