^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/log2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/math64.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <dt-bindings/iio/qcom,spmi-vadc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "qcom-vadc-common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define ADC5_USR_REVISION1 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define ADC5_USR_STATUS1 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define ADC5_USR_STATUS1_CONV_FAULT BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define ADC5_USR_STATUS1_REQ_STS BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define ADC5_USR_STATUS1_EOC BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define ADC5_USR_STATUS1_REQ_STS_EOC_MASK 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define ADC5_USR_STATUS2 0x9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define ADC5_USR_STATUS2_CONV_SEQ_MASK 0x70
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define ADC5_USR_STATUS2_CONV_SEQ_MASK_SHIFT 0x5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define ADC5_USR_IBAT_MEAS 0xf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define ADC5_USR_IBAT_MEAS_SUPPORTED BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define ADC5_USR_DIG_PARAM 0x42
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define ADC5_USR_DIG_PARAM_CAL_VAL BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define ADC5_USR_DIG_PARAM_CAL_VAL_SHIFT 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define ADC5_USR_DIG_PARAM_CAL_SEL 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define ADC5_USR_DIG_PARAM_CAL_SEL_SHIFT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define ADC5_USR_DIG_PARAM_DEC_RATIO_SEL 0xc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define ADC5_USR_DIG_PARAM_DEC_RATIO_SEL_SHIFT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define ADC5_USR_FAST_AVG_CTL 0x43
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define ADC5_USR_FAST_AVG_CTL_EN BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define ADC5_USR_FAST_AVG_CTL_SAMPLES_MASK 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define ADC5_USR_CH_SEL_CTL 0x44
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define ADC5_USR_DELAY_CTL 0x45
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define ADC5_USR_HW_SETTLE_DELAY_MASK 0xf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define ADC5_USR_EN_CTL1 0x46
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define ADC5_USR_EN_CTL1_ADC_EN BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define ADC5_USR_CONV_REQ 0x47
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define ADC5_USR_CONV_REQ_REQ BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define ADC5_USR_DATA0 0x50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define ADC5_USR_DATA1 0x51
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define ADC5_USR_IBAT_DATA0 0x52
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define ADC5_USR_IBAT_DATA1 0x53
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define ADC_CHANNEL_OFFSET 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define ADC_CHANNEL_MASK GENMASK(7, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * Conversion time varies based on the decimation, clock rate, fast average
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * samples and measurements queued across different VADC peripherals.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * Set the timeout to a max of 100ms.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define ADC5_CONV_TIME_MIN_US 263
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define ADC5_CONV_TIME_MAX_US 264
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define ADC5_CONV_TIME_RETRY 400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define ADC5_CONV_TIMEOUT msecs_to_jiffies(100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* Digital version >= 5.3 supports hw_settle_2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define ADC5_HW_SETTLE_DIFF_MINOR 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define ADC5_HW_SETTLE_DIFF_MAJOR 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /* For PMIC7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define ADC_APP_SID 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define ADC_APP_SID_MASK GENMASK(3, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define ADC7_CONV_TIMEOUT msecs_to_jiffies(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) enum adc5_cal_method {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) ADC5_NO_CAL = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) ADC5_RATIOMETRIC_CAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) ADC5_ABSOLUTE_CAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) enum adc5_cal_val {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) ADC5_TIMER_CAL = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) ADC5_NEW_CAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * struct adc5_channel_prop - ADC channel property.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * @channel: channel number, refer to the channel list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * @cal_method: calibration method.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * @cal_val: calibration value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * @decimation: sampling rate supported for the channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * @sid: slave id of PMIC owning the channel, for PMIC7.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * @prescale: channel scaling performed on the input signal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * @hw_settle_time: the time between AMUX being configured and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * start of conversion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * @avg_samples: ability to provide single result from the ADC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * that is an average of multiple measurements.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * @scale_fn_type: Represents the scaling function to convert voltage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * physical units desired by the client for the channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * @datasheet_name: Channel name used in device tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct adc5_channel_prop {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) unsigned int channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) enum adc5_cal_method cal_method;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) enum adc5_cal_val cal_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) unsigned int decimation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) unsigned int sid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) unsigned int prescale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) unsigned int hw_settle_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) unsigned int avg_samples;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) enum vadc_scale_fn_type scale_fn_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) const char *datasheet_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * struct adc5_chip - ADC private structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * @regmap: SPMI ADC5 peripheral register map field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * @dev: SPMI ADC5 device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * @base: base address for the ADC peripheral.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * @nchannels: number of ADC channels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * @chan_props: array of ADC channel properties.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * @iio_chans: array of IIO channels specification.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * @poll_eoc: use polling instead of interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * @complete: ADC result notification after interrupt is received.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * @lock: ADC lock for access to the peripheral.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * @data: software configuration data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) struct adc5_chip {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) u16 base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) unsigned int nchannels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct adc5_channel_prop *chan_props;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct iio_chan_spec *iio_chans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) bool poll_eoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct completion complete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) const struct adc5_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static const struct vadc_prescale_ratio adc5_prescale_ratios[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {.num = 1, .den = 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {.num = 1, .den = 3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {.num = 1, .den = 4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {.num = 1, .den = 6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {.num = 1, .den = 20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {.num = 1, .den = 8},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) {.num = 10, .den = 81},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {.num = 1, .den = 10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {.num = 1, .den = 16}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static int adc5_read(struct adc5_chip *adc, u16 offset, u8 *data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return regmap_bulk_read(adc->regmap, adc->base + offset, data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static int adc5_write(struct adc5_chip *adc, u16 offset, u8 *data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) return regmap_bulk_write(adc->regmap, adc->base + offset, data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static int adc5_masked_write(struct adc5_chip *adc, u16 offset, u8 mask, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return regmap_update_bits(adc->regmap, adc->base + offset, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static int adc5_prescaling_from_dt(u32 num, u32 den)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) unsigned int pre;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) for (pre = 0; pre < ARRAY_SIZE(adc5_prescale_ratios); pre++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (adc5_prescale_ratios[pre].num == num &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) adc5_prescale_ratios[pre].den == den)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (pre == ARRAY_SIZE(adc5_prescale_ratios))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return pre;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static int adc5_hw_settle_time_from_dt(u32 value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) const unsigned int *hw_settle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) for (i = 0; i < VADC_HW_SETTLE_SAMPLES_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (value == hw_settle[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static int adc5_avg_samples_from_dt(u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (!is_power_of_2(value) || value > ADC5_AVG_SAMPLES_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) return __ffs(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) static int adc5_decimation_from_dt(u32 value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) const unsigned int *decimation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) for (i = 0; i < ADC5_DECIMATION_SAMPLES_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (value == decimation[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static int adc5_read_voltage_data(struct adc5_chip *adc, u16 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) u8 rslt_lsb, rslt_msb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) ret = adc5_read(adc, ADC5_USR_DATA0, &rslt_lsb, sizeof(rslt_lsb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) ret = adc5_read(adc, ADC5_USR_DATA1, &rslt_msb, sizeof(rslt_lsb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) *data = (rslt_msb << 8) | rslt_lsb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (*data == ADC5_USR_DATA_CHECK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) dev_err(adc->dev, "Invalid data:0x%x\n", *data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) dev_dbg(adc->dev, "voltage raw code:0x%x\n", *data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static int adc5_poll_wait_eoc(struct adc5_chip *adc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) unsigned int count, retry = ADC5_CONV_TIME_RETRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) u8 status1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) for (count = 0; count < retry; count++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) ret = adc5_read(adc, ADC5_USR_STATUS1, &status1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) sizeof(status1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) status1 &= ADC5_USR_STATUS1_REQ_STS_EOC_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (status1 == ADC5_USR_STATUS1_EOC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) usleep_range(ADC5_CONV_TIME_MIN_US, ADC5_CONV_TIME_MAX_US);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static void adc5_update_dig_param(struct adc5_chip *adc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct adc5_channel_prop *prop, u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) /* Update calibration value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) *data &= ~ADC5_USR_DIG_PARAM_CAL_VAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) *data |= (prop->cal_val << ADC5_USR_DIG_PARAM_CAL_VAL_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /* Update calibration select */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) *data &= ~ADC5_USR_DIG_PARAM_CAL_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) *data |= (prop->cal_method << ADC5_USR_DIG_PARAM_CAL_SEL_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) /* Update decimation ratio select */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) *data &= ~ADC5_USR_DIG_PARAM_DEC_RATIO_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) *data |= (prop->decimation << ADC5_USR_DIG_PARAM_DEC_RATIO_SEL_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static int adc5_configure(struct adc5_chip *adc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) struct adc5_channel_prop *prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) u8 buf[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /* Read registers 0x42 through 0x46 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) ret = adc5_read(adc, ADC5_USR_DIG_PARAM, buf, sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /* Digital param selection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) adc5_update_dig_param(adc, prop, &buf[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) /* Update fast average sample value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) buf[1] &= (u8) ~ADC5_USR_FAST_AVG_CTL_SAMPLES_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) buf[1] |= prop->avg_samples;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) /* Select ADC channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) buf[2] = prop->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) /* Select HW settle delay for channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) buf[3] &= (u8) ~ADC5_USR_HW_SETTLE_DELAY_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) buf[3] |= prop->hw_settle_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) /* Select ADC enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) buf[4] |= ADC5_USR_EN_CTL1_ADC_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) /* Select CONV request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) buf[5] |= ADC5_USR_CONV_REQ_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (!adc->poll_eoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) reinit_completion(&adc->complete);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return adc5_write(adc, ADC5_USR_DIG_PARAM, buf, sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) static int adc7_configure(struct adc5_chip *adc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) struct adc5_channel_prop *prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) u8 conv_req = 0, buf[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) ret = adc5_masked_write(adc, ADC_APP_SID, ADC_APP_SID_MASK, prop->sid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) ret = adc5_read(adc, ADC5_USR_DIG_PARAM, buf, sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) /* Digital param selection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) adc5_update_dig_param(adc, prop, &buf[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) /* Update fast average sample value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) buf[1] &= ~ADC5_USR_FAST_AVG_CTL_SAMPLES_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) buf[1] |= prop->avg_samples;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /* Select ADC channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) buf[2] = prop->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) /* Select HW settle delay for channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) buf[3] &= ~ADC5_USR_HW_SETTLE_DELAY_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) buf[3] |= prop->hw_settle_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) /* Select CONV request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) conv_req = ADC5_USR_CONV_REQ_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (!adc->poll_eoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) reinit_completion(&adc->complete);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) ret = adc5_write(adc, ADC5_USR_DIG_PARAM, buf, sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return adc5_write(adc, ADC5_USR_CONV_REQ, &conv_req, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) static int adc5_do_conversion(struct adc5_chip *adc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) struct adc5_channel_prop *prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) u16 *data_volt, u16 *data_cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) mutex_lock(&adc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) ret = adc5_configure(adc, prop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) dev_err(adc->dev, "ADC configure failed with %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (adc->poll_eoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) ret = adc5_poll_wait_eoc(adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) dev_err(adc->dev, "EOC bit not set\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) ret = wait_for_completion_timeout(&adc->complete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) ADC5_CONV_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) dev_dbg(adc->dev, "Did not get completion timeout.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) ret = adc5_poll_wait_eoc(adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) dev_err(adc->dev, "EOC bit not set\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) ret = adc5_read_voltage_data(adc, data_volt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) mutex_unlock(&adc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) static int adc7_do_conversion(struct adc5_chip *adc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) struct adc5_channel_prop *prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) u16 *data_volt, u16 *data_cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) u8 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) mutex_lock(&adc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) ret = adc7_configure(adc, prop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) dev_err(adc->dev, "ADC configure failed with %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) /* No support for polling mode at present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) wait_for_completion_timeout(&adc->complete, ADC7_CONV_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) ret = adc5_read(adc, ADC5_USR_STATUS1, &status, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (status & ADC5_USR_STATUS1_CONV_FAULT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) dev_err(adc->dev, "Unexpected conversion fault\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) ret = adc5_read_voltage_data(adc, data_volt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) mutex_unlock(&adc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) typedef int (*adc_do_conversion)(struct adc5_chip *adc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) struct adc5_channel_prop *prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) u16 *data_volt, u16 *data_cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) static irqreturn_t adc5_isr(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) struct adc5_chip *adc = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) complete(&adc->complete);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) static int adc5_of_xlate(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) const struct of_phandle_args *iiospec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) struct adc5_chip *adc = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) for (i = 0; i < adc->nchannels; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (adc->chan_props[i].channel == iiospec->args[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) static int adc7_of_xlate(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) const struct of_phandle_args *iiospec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) struct adc5_chip *adc = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) int i, v_channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) for (i = 0; i < adc->nchannels; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) v_channel = (adc->chan_props[i].sid << ADC_CHANNEL_OFFSET) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) adc->chan_props[i].channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (v_channel == iiospec->args[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) static int adc_read_raw_common(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) struct iio_chan_spec const *chan, int *val, int *val2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) long mask, adc_do_conversion do_conv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) struct adc5_chip *adc = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) struct adc5_channel_prop *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) u16 adc_code_volt, adc_code_cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) prop = &adc->chan_props[chan->address];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) case IIO_CHAN_INFO_PROCESSED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) ret = do_conv(adc, prop, chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) &adc_code_volt, &adc_code_cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) ret = qcom_adc5_hw_scale(prop->scale_fn_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) &adc5_prescale_ratios[prop->prescale],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) adc->data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) adc_code_volt, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static int adc5_read_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) struct iio_chan_spec const *chan, int *val, int *val2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) return adc_read_raw_common(indio_dev, chan, val, val2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) mask, adc5_do_conversion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) static int adc7_read_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) struct iio_chan_spec const *chan, int *val, int *val2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) return adc_read_raw_common(indio_dev, chan, val, val2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) mask, adc7_do_conversion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) static const struct iio_info adc5_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) .read_raw = adc5_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) .of_xlate = adc5_of_xlate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) static const struct iio_info adc7_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) .read_raw = adc7_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) .of_xlate = adc7_of_xlate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) struct adc5_channels {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) const char *datasheet_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) unsigned int prescale_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) enum iio_chan_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) long info_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) enum vadc_scale_fn_type scale_fn_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) /* In these definitions, _pre refers to an index into adc5_prescale_ratios. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) #define ADC5_CHAN(_dname, _type, _mask, _pre, _scale) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) .datasheet_name = _dname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) .prescale_index = _pre, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) .type = _type, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) .info_mask = _mask, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) .scale_fn_type = _scale, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) #define ADC5_CHAN_TEMP(_dname, _pre, _scale) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) ADC5_CHAN(_dname, IIO_TEMP, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) BIT(IIO_CHAN_INFO_PROCESSED), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) _pre, _scale) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) #define ADC5_CHAN_VOLT(_dname, _pre, _scale) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) ADC5_CHAN(_dname, IIO_VOLTAGE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) BIT(IIO_CHAN_INFO_PROCESSED), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) _pre, _scale) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) static const struct adc5_channels adc5_chans_pmic[ADC5_MAX_CHANNEL] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) [ADC5_REF_GND] = ADC5_CHAN_VOLT("ref_gnd", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) SCALE_HW_CALIB_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) [ADC5_1P25VREF] = ADC5_CHAN_VOLT("vref_1p25", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) SCALE_HW_CALIB_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) [ADC5_VPH_PWR] = ADC5_CHAN_VOLT("vph_pwr", 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) SCALE_HW_CALIB_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) [ADC5_VBAT_SNS] = ADC5_CHAN_VOLT("vbat_sns", 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) SCALE_HW_CALIB_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) [ADC5_DIE_TEMP] = ADC5_CHAN_TEMP("die_temp", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) SCALE_HW_CALIB_PMIC_THERM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) [ADC5_USB_IN_I] = ADC5_CHAN_VOLT("usb_in_i_uv", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) SCALE_HW_CALIB_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) [ADC5_USB_IN_V_16] = ADC5_CHAN_VOLT("usb_in_v_div_16", 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) SCALE_HW_CALIB_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) [ADC5_CHG_TEMP] = ADC5_CHAN_TEMP("chg_temp", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) SCALE_HW_CALIB_PM5_CHG_TEMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) /* Charger prescales SBUx and MID_CHG to fit within 1.8V upper unit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) [ADC5_SBUx] = ADC5_CHAN_VOLT("chg_sbux", 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) SCALE_HW_CALIB_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) [ADC5_MID_CHG_DIV6] = ADC5_CHAN_VOLT("chg_mid_chg", 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) SCALE_HW_CALIB_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) [ADC5_XO_THERM_100K_PU] = ADC5_CHAN_TEMP("xo_therm", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) SCALE_HW_CALIB_XOTHERM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) [ADC5_AMUX_THM1_100K_PU] = ADC5_CHAN_TEMP("amux_thm1_100k_pu", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) SCALE_HW_CALIB_THERM_100K_PULLUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) [ADC5_AMUX_THM2_100K_PU] = ADC5_CHAN_TEMP("amux_thm2_100k_pu", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) SCALE_HW_CALIB_THERM_100K_PULLUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) [ADC5_AMUX_THM3_100K_PU] = ADC5_CHAN_TEMP("amux_thm3_100k_pu", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) SCALE_HW_CALIB_THERM_100K_PULLUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) [ADC5_AMUX_THM2] = ADC5_CHAN_TEMP("amux_thm2", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) SCALE_HW_CALIB_PM5_SMB_TEMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) static const struct adc5_channels adc7_chans_pmic[ADC5_MAX_CHANNEL] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) [ADC7_REF_GND] = ADC5_CHAN_VOLT("ref_gnd", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) SCALE_HW_CALIB_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) [ADC7_1P25VREF] = ADC5_CHAN_VOLT("vref_1p25", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) SCALE_HW_CALIB_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) [ADC7_VPH_PWR] = ADC5_CHAN_VOLT("vph_pwr", 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) SCALE_HW_CALIB_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) [ADC7_VBAT_SNS] = ADC5_CHAN_VOLT("vbat_sns", 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) SCALE_HW_CALIB_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) [ADC7_DIE_TEMP] = ADC5_CHAN_TEMP("die_temp", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) SCALE_HW_CALIB_PMIC_THERM_PM7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) [ADC7_AMUX_THM1_100K_PU] = ADC5_CHAN_TEMP("amux_thm1_pu2", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) SCALE_HW_CALIB_THERM_100K_PU_PM7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) [ADC7_AMUX_THM2_100K_PU] = ADC5_CHAN_TEMP("amux_thm2_pu2", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) SCALE_HW_CALIB_THERM_100K_PU_PM7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) [ADC7_AMUX_THM3_100K_PU] = ADC5_CHAN_TEMP("amux_thm3_pu2", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) SCALE_HW_CALIB_THERM_100K_PU_PM7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) [ADC7_AMUX_THM4_100K_PU] = ADC5_CHAN_TEMP("amux_thm4_pu2", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) SCALE_HW_CALIB_THERM_100K_PU_PM7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) [ADC7_AMUX_THM5_100K_PU] = ADC5_CHAN_TEMP("amux_thm5_pu2", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) SCALE_HW_CALIB_THERM_100K_PU_PM7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) [ADC7_AMUX_THM6_100K_PU] = ADC5_CHAN_TEMP("amux_thm6_pu2", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) SCALE_HW_CALIB_THERM_100K_PU_PM7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) [ADC7_GPIO1_100K_PU] = ADC5_CHAN_TEMP("gpio1_pu2", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) SCALE_HW_CALIB_THERM_100K_PU_PM7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) [ADC7_GPIO2_100K_PU] = ADC5_CHAN_TEMP("gpio2_pu2", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) SCALE_HW_CALIB_THERM_100K_PU_PM7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) [ADC7_GPIO3_100K_PU] = ADC5_CHAN_TEMP("gpio3_pu2", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) SCALE_HW_CALIB_THERM_100K_PU_PM7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) [ADC7_GPIO4_100K_PU] = ADC5_CHAN_TEMP("gpio4_pu2", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) SCALE_HW_CALIB_THERM_100K_PU_PM7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) static const struct adc5_channels adc5_chans_rev2[ADC5_MAX_CHANNEL] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) [ADC5_REF_GND] = ADC5_CHAN_VOLT("ref_gnd", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) SCALE_HW_CALIB_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) [ADC5_1P25VREF] = ADC5_CHAN_VOLT("vref_1p25", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) SCALE_HW_CALIB_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) [ADC5_VPH_PWR] = ADC5_CHAN_VOLT("vph_pwr", 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) SCALE_HW_CALIB_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) [ADC5_VBAT_SNS] = ADC5_CHAN_VOLT("vbat_sns", 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) SCALE_HW_CALIB_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) [ADC5_VCOIN] = ADC5_CHAN_VOLT("vcoin", 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) SCALE_HW_CALIB_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) [ADC5_DIE_TEMP] = ADC5_CHAN_TEMP("die_temp", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) SCALE_HW_CALIB_PMIC_THERM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) [ADC5_AMUX_THM1_100K_PU] = ADC5_CHAN_TEMP("amux_thm1_100k_pu", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) SCALE_HW_CALIB_THERM_100K_PULLUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) [ADC5_AMUX_THM2_100K_PU] = ADC5_CHAN_TEMP("amux_thm2_100k_pu", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) SCALE_HW_CALIB_THERM_100K_PULLUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) [ADC5_AMUX_THM3_100K_PU] = ADC5_CHAN_TEMP("amux_thm3_100k_pu", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) SCALE_HW_CALIB_THERM_100K_PULLUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) [ADC5_AMUX_THM4_100K_PU] = ADC5_CHAN_TEMP("amux_thm4_100k_pu", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) SCALE_HW_CALIB_THERM_100K_PULLUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) [ADC5_AMUX_THM5_100K_PU] = ADC5_CHAN_TEMP("amux_thm5_100k_pu", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) SCALE_HW_CALIB_THERM_100K_PULLUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) [ADC5_XO_THERM_100K_PU] = ADC5_CHAN_TEMP("xo_therm_100k_pu", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) SCALE_HW_CALIB_THERM_100K_PULLUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) static int adc5_get_dt_channel_data(struct adc5_chip *adc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) struct adc5_channel_prop *prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) struct device_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) const struct adc5_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) const char *name = node->name, *channel_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) u32 chan, value, varr[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) u32 sid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) struct device *dev = adc->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) ret = of_property_read_u32(node, "reg", &chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) dev_err(dev, "invalid channel number %s\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) /* Value read from "reg" is virtual channel number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) /* virtual channel number = sid << 8 | channel number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) if (adc->data->info == &adc7_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) sid = chan >> ADC_CHANNEL_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) chan = chan & ADC_CHANNEL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (chan > ADC5_PARALLEL_ISENSE_VBAT_IDATA ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) !data->adc_chans[chan].datasheet_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) dev_err(dev, "%s invalid channel number %d\n", name, chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) /* the channel has DT description */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) prop->channel = chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) prop->sid = sid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) channel_name = of_get_property(node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) "label", NULL) ? : node->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (!channel_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) dev_err(dev, "Invalid channel name\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) prop->datasheet_name = channel_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) ret = of_property_read_u32(node, "qcom,decimation", &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) ret = adc5_decimation_from_dt(value, data->decimation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) dev_err(dev, "%02x invalid decimation %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) chan, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) prop->decimation = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) prop->decimation = ADC5_DECIMATION_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) ret = of_property_read_u32_array(node, "qcom,pre-scaling", varr, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) ret = adc5_prescaling_from_dt(varr[0], varr[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) dev_err(dev, "%02x invalid pre-scaling <%d %d>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) chan, varr[0], varr[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) prop->prescale = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) prop->prescale =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) adc->data->adc_chans[prop->channel].prescale_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) ret = of_property_read_u32(node, "qcom,hw-settle-time", &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) u8 dig_version[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) ret = adc5_read(adc, ADC5_USR_REVISION1, dig_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) sizeof(dig_version));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) dev_err(dev, "Invalid dig version read %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) dev_dbg(dev, "dig_ver:minor:%d, major:%d\n", dig_version[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) dig_version[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) /* Digital controller >= 5.3 have hw_settle_2 option */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if ((dig_version[0] >= ADC5_HW_SETTLE_DIFF_MINOR &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) dig_version[1] >= ADC5_HW_SETTLE_DIFF_MAJOR) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) adc->data->info == &adc7_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) ret = adc5_hw_settle_time_from_dt(value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) data->hw_settle_2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) ret = adc5_hw_settle_time_from_dt(value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) data->hw_settle_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) dev_err(dev, "%02x invalid hw-settle-time %d us\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) chan, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) prop->hw_settle_time = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) prop->hw_settle_time = VADC_DEF_HW_SETTLE_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) ret = of_property_read_u32(node, "qcom,avg-samples", &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) ret = adc5_avg_samples_from_dt(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) dev_err(dev, "%02x invalid avg-samples %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) chan, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) prop->avg_samples = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) prop->avg_samples = VADC_DEF_AVG_SAMPLES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) if (of_property_read_bool(node, "qcom,ratiometric"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) prop->cal_method = ADC5_RATIOMETRIC_CAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) prop->cal_method = ADC5_ABSOLUTE_CAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) * Default to using timer calibration. Using a fresh calibration value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) * for every conversion will increase the overall time for a request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) prop->cal_val = ADC5_TIMER_CAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) dev_dbg(dev, "%02x name %s\n", chan, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) static const struct adc5_data adc5_data_pmic = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) .full_scale_code_volt = 0x70e4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) .full_scale_code_cur = 0x2710,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) .adc_chans = adc5_chans_pmic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) .info = &adc5_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) .decimation = (unsigned int [ADC5_DECIMATION_SAMPLES_MAX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) {250, 420, 840},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) .hw_settle_1 = (unsigned int [VADC_HW_SETTLE_SAMPLES_MAX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) {15, 100, 200, 300, 400, 500, 600, 700,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 800, 900, 1, 2, 4, 6, 8, 10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) .hw_settle_2 = (unsigned int [VADC_HW_SETTLE_SAMPLES_MAX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) {15, 100, 200, 300, 400, 500, 600, 700,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 1, 2, 4, 8, 16, 32, 64, 128},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) static const struct adc5_data adc7_data_pmic = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) .full_scale_code_volt = 0x70e4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) .adc_chans = adc7_chans_pmic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) .info = &adc7_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) .decimation = (unsigned int [ADC5_DECIMATION_SAMPLES_MAX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) {85, 340, 1360},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) .hw_settle_2 = (unsigned int [VADC_HW_SETTLE_SAMPLES_MAX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) {15, 100, 200, 300, 400, 500, 600, 700,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 1000, 2000, 4000, 8000, 16000, 32000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 64000, 128000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) static const struct adc5_data adc5_data_pmic_rev2 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) .full_scale_code_volt = 0x4000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) .full_scale_code_cur = 0x1800,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) .adc_chans = adc5_chans_rev2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) .info = &adc5_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) .decimation = (unsigned int [ADC5_DECIMATION_SAMPLES_MAX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) {256, 512, 1024},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) .hw_settle_1 = (unsigned int [VADC_HW_SETTLE_SAMPLES_MAX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) {0, 100, 200, 300, 400, 500, 600, 700,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 800, 900, 1, 2, 4, 6, 8, 10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) .hw_settle_2 = (unsigned int [VADC_HW_SETTLE_SAMPLES_MAX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) {15, 100, 200, 300, 400, 500, 600, 700,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 1, 2, 4, 8, 16, 32, 64, 128},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) static const struct of_device_id adc5_match_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) .compatible = "qcom,spmi-adc5",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) .data = &adc5_data_pmic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) .compatible = "qcom,spmi-adc7",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) .data = &adc7_data_pmic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) .compatible = "qcom,spmi-adc-rev2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) .data = &adc5_data_pmic_rev2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) MODULE_DEVICE_TABLE(of, adc5_match_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) static int adc5_get_dt_data(struct adc5_chip *adc, struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) const struct adc5_channels *adc_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) struct iio_chan_spec *iio_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) struct adc5_channel_prop prop, *chan_props;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) struct device_node *child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) unsigned int index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) const struct of_device_id *id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) const struct adc5_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) adc->nchannels = of_get_available_child_count(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) if (!adc->nchannels)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) adc->iio_chans = devm_kcalloc(adc->dev, adc->nchannels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) sizeof(*adc->iio_chans), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) if (!adc->iio_chans)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) adc->chan_props = devm_kcalloc(adc->dev, adc->nchannels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) sizeof(*adc->chan_props), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) if (!adc->chan_props)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) chan_props = adc->chan_props;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) iio_chan = adc->iio_chans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) id = of_match_node(adc5_match_table, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) if (id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) data = id->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) data = &adc5_data_pmic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) adc->data = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) for_each_available_child_of_node(node, child) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) ret = adc5_get_dt_channel_data(adc, &prop, child, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) of_node_put(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) prop.scale_fn_type =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) data->adc_chans[prop.channel].scale_fn_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) *chan_props = prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) adc_chan = &data->adc_chans[prop.channel];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) iio_chan->channel = prop.channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) iio_chan->datasheet_name = prop.datasheet_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) iio_chan->extend_name = prop.datasheet_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) iio_chan->info_mask_separate = adc_chan->info_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) iio_chan->type = adc_chan->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) iio_chan->address = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) iio_chan++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) chan_props++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) static int adc5_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) struct device_node *node = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) struct iio_dev *indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) struct adc5_chip *adc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) int ret, irq_eoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) regmap = dev_get_regmap(dev->parent, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) if (!regmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) ret = of_property_read_u32(node, "reg", ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) indio_dev = devm_iio_device_alloc(dev, sizeof(*adc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if (!indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) adc = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) adc->regmap = regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) adc->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) adc->base = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) init_completion(&adc->complete);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) mutex_init(&adc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) ret = adc5_get_dt_data(adc, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) dev_err(dev, "adc get dt data failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) irq_eoc = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) if (irq_eoc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (irq_eoc == -EPROBE_DEFER || irq_eoc == -EINVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) return irq_eoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) adc->poll_eoc = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) ret = devm_request_irq(dev, irq_eoc, adc5_isr, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) "pm-adc5", adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) indio_dev->name = pdev->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) indio_dev->modes = INDIO_DIRECT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) indio_dev->info = adc->data->info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) indio_dev->channels = adc->iio_chans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) indio_dev->num_channels = adc->nchannels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) return devm_iio_device_register(dev, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) static struct platform_driver adc5_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) .name = "qcom-spmi-adc5",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) .of_match_table = adc5_match_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) .probe = adc5_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) module_platform_driver(adc5_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) MODULE_ALIAS("platform:qcom-spmi-adc5");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) MODULE_DESCRIPTION("Qualcomm Technologies Inc. PMIC5 ADC driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) MODULE_LICENSE("GPL v2");