1e13d7572SSiddartha Mohanadoss // SPDX-License-Identifier: GPL-2.0 2e13d7572SSiddartha Mohanadoss /* 3082111e5SJishnu Prakash * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. 4e13d7572SSiddartha Mohanadoss */ 5e13d7572SSiddartha Mohanadoss 6e13d7572SSiddartha Mohanadoss #include <linux/bitops.h> 7e13d7572SSiddartha Mohanadoss #include <linux/completion.h> 8e13d7572SSiddartha Mohanadoss #include <linux/delay.h> 9e13d7572SSiddartha Mohanadoss #include <linux/err.h> 10ec82edb2SDmitry Baryshkov #include <linux/iio/adc/qcom-vadc-common.h> 11e13d7572SSiddartha Mohanadoss #include <linux/iio/iio.h> 12e13d7572SSiddartha Mohanadoss #include <linux/interrupt.h> 13e13d7572SSiddartha Mohanadoss #include <linux/kernel.h> 14e13d7572SSiddartha Mohanadoss #include <linux/log2.h> 15e13d7572SSiddartha Mohanadoss #include <linux/math64.h> 16e13d7572SSiddartha Mohanadoss #include <linux/module.h> 174f47a236SNuno Sá #include <linux/mod_devicetable.h> 18e13d7572SSiddartha Mohanadoss #include <linux/platform_device.h> 194f47a236SNuno Sá #include <linux/property.h> 20e13d7572SSiddartha Mohanadoss #include <linux/regmap.h> 21e13d7572SSiddartha Mohanadoss #include <linux/slab.h> 22e13d7572SSiddartha Mohanadoss 23e13d7572SSiddartha Mohanadoss #include <dt-bindings/iio/qcom,spmi-vadc.h> 24e13d7572SSiddartha Mohanadoss 25e13d7572SSiddartha Mohanadoss #define ADC5_USR_REVISION1 0x0 26e13d7572SSiddartha Mohanadoss #define ADC5_USR_STATUS1 0x8 27082111e5SJishnu Prakash #define ADC5_USR_STATUS1_CONV_FAULT BIT(7) 28e13d7572SSiddartha Mohanadoss #define ADC5_USR_STATUS1_REQ_STS BIT(1) 29e13d7572SSiddartha Mohanadoss #define ADC5_USR_STATUS1_EOC BIT(0) 30e13d7572SSiddartha Mohanadoss #define ADC5_USR_STATUS1_REQ_STS_EOC_MASK 0x3 31e13d7572SSiddartha Mohanadoss 32e13d7572SSiddartha Mohanadoss #define ADC5_USR_STATUS2 0x9 33e13d7572SSiddartha Mohanadoss #define ADC5_USR_STATUS2_CONV_SEQ_MASK 0x70 34e13d7572SSiddartha Mohanadoss #define ADC5_USR_STATUS2_CONV_SEQ_MASK_SHIFT 0x5 35e13d7572SSiddartha Mohanadoss 36e13d7572SSiddartha Mohanadoss #define ADC5_USR_IBAT_MEAS 0xf 37e13d7572SSiddartha Mohanadoss #define ADC5_USR_IBAT_MEAS_SUPPORTED BIT(0) 38e13d7572SSiddartha Mohanadoss 39e13d7572SSiddartha Mohanadoss #define ADC5_USR_DIG_PARAM 0x42 40e13d7572SSiddartha Mohanadoss #define ADC5_USR_DIG_PARAM_CAL_VAL BIT(6) 41e13d7572SSiddartha Mohanadoss #define ADC5_USR_DIG_PARAM_CAL_VAL_SHIFT 6 42e13d7572SSiddartha Mohanadoss #define ADC5_USR_DIG_PARAM_CAL_SEL 0x30 43e13d7572SSiddartha Mohanadoss #define ADC5_USR_DIG_PARAM_CAL_SEL_SHIFT 4 44e13d7572SSiddartha Mohanadoss #define ADC5_USR_DIG_PARAM_DEC_RATIO_SEL 0xc 45e13d7572SSiddartha Mohanadoss #define ADC5_USR_DIG_PARAM_DEC_RATIO_SEL_SHIFT 2 46e13d7572SSiddartha Mohanadoss 47e13d7572SSiddartha Mohanadoss #define ADC5_USR_FAST_AVG_CTL 0x43 48e13d7572SSiddartha Mohanadoss #define ADC5_USR_FAST_AVG_CTL_EN BIT(7) 49e13d7572SSiddartha Mohanadoss #define ADC5_USR_FAST_AVG_CTL_SAMPLES_MASK 0x7 50e13d7572SSiddartha Mohanadoss 51e13d7572SSiddartha Mohanadoss #define ADC5_USR_CH_SEL_CTL 0x44 52e13d7572SSiddartha Mohanadoss 53e13d7572SSiddartha Mohanadoss #define ADC5_USR_DELAY_CTL 0x45 54e13d7572SSiddartha Mohanadoss #define ADC5_USR_HW_SETTLE_DELAY_MASK 0xf 55e13d7572SSiddartha Mohanadoss 56e13d7572SSiddartha Mohanadoss #define ADC5_USR_EN_CTL1 0x46 57e13d7572SSiddartha Mohanadoss #define ADC5_USR_EN_CTL1_ADC_EN BIT(7) 58e13d7572SSiddartha Mohanadoss 59e13d7572SSiddartha Mohanadoss #define ADC5_USR_CONV_REQ 0x47 60e13d7572SSiddartha Mohanadoss #define ADC5_USR_CONV_REQ_REQ BIT(7) 61e13d7572SSiddartha Mohanadoss 62e13d7572SSiddartha Mohanadoss #define ADC5_USR_DATA0 0x50 63e13d7572SSiddartha Mohanadoss 64e13d7572SSiddartha Mohanadoss #define ADC5_USR_DATA1 0x51 65e13d7572SSiddartha Mohanadoss 66e13d7572SSiddartha Mohanadoss #define ADC5_USR_IBAT_DATA0 0x52 67e13d7572SSiddartha Mohanadoss 68e13d7572SSiddartha Mohanadoss #define ADC5_USR_IBAT_DATA1 0x53 69e13d7572SSiddartha Mohanadoss 70082111e5SJishnu Prakash #define ADC_CHANNEL_OFFSET 0x8 71082111e5SJishnu Prakash #define ADC_CHANNEL_MASK GENMASK(7, 0) 72082111e5SJishnu Prakash 73e13d7572SSiddartha Mohanadoss /* 74e13d7572SSiddartha Mohanadoss * Conversion time varies based on the decimation, clock rate, fast average 75e13d7572SSiddartha Mohanadoss * samples and measurements queued across different VADC peripherals. 76e13d7572SSiddartha Mohanadoss * Set the timeout to a max of 100ms. 77e13d7572SSiddartha Mohanadoss */ 78e13d7572SSiddartha Mohanadoss #define ADC5_CONV_TIME_MIN_US 263 79e13d7572SSiddartha Mohanadoss #define ADC5_CONV_TIME_MAX_US 264 80e13d7572SSiddartha Mohanadoss #define ADC5_CONV_TIME_RETRY 400 81e13d7572SSiddartha Mohanadoss #define ADC5_CONV_TIMEOUT msecs_to_jiffies(100) 82e13d7572SSiddartha Mohanadoss 83e13d7572SSiddartha Mohanadoss /* Digital version >= 5.3 supports hw_settle_2 */ 84e13d7572SSiddartha Mohanadoss #define ADC5_HW_SETTLE_DIFF_MINOR 3 85e13d7572SSiddartha Mohanadoss #define ADC5_HW_SETTLE_DIFF_MAJOR 5 86e13d7572SSiddartha Mohanadoss 87082111e5SJishnu Prakash /* For PMIC7 */ 88082111e5SJishnu Prakash #define ADC_APP_SID 0x40 89082111e5SJishnu Prakash #define ADC_APP_SID_MASK GENMASK(3, 0) 90082111e5SJishnu Prakash #define ADC7_CONV_TIMEOUT msecs_to_jiffies(10) 91082111e5SJishnu Prakash 92e13d7572SSiddartha Mohanadoss enum adc5_cal_method { 93e13d7572SSiddartha Mohanadoss ADC5_NO_CAL = 0, 94e13d7572SSiddartha Mohanadoss ADC5_RATIOMETRIC_CAL, 95e13d7572SSiddartha Mohanadoss ADC5_ABSOLUTE_CAL 96e13d7572SSiddartha Mohanadoss }; 97e13d7572SSiddartha Mohanadoss 98e13d7572SSiddartha Mohanadoss enum adc5_cal_val { 99e13d7572SSiddartha Mohanadoss ADC5_TIMER_CAL = 0, 100e13d7572SSiddartha Mohanadoss ADC5_NEW_CAL 101e13d7572SSiddartha Mohanadoss }; 102e13d7572SSiddartha Mohanadoss 103e13d7572SSiddartha Mohanadoss /** 104e13d7572SSiddartha Mohanadoss * struct adc5_channel_prop - ADC channel property. 105e13d7572SSiddartha Mohanadoss * @channel: channel number, refer to the channel list. 106e13d7572SSiddartha Mohanadoss * @cal_method: calibration method. 107e13d7572SSiddartha Mohanadoss * @cal_val: calibration value 108e13d7572SSiddartha Mohanadoss * @decimation: sampling rate supported for the channel. 109082111e5SJishnu Prakash * @sid: slave id of PMIC owning the channel, for PMIC7. 110e13d7572SSiddartha Mohanadoss * @prescale: channel scaling performed on the input signal. 111e13d7572SSiddartha Mohanadoss * @hw_settle_time: the time between AMUX being configured and the 112e13d7572SSiddartha Mohanadoss * start of conversion. 113e13d7572SSiddartha Mohanadoss * @avg_samples: ability to provide single result from the ADC 114e13d7572SSiddartha Mohanadoss * that is an average of multiple measurements. 115e13d7572SSiddartha Mohanadoss * @scale_fn_type: Represents the scaling function to convert voltage 116e13d7572SSiddartha Mohanadoss * physical units desired by the client for the channel. 117e93cde03SMarijn Suijten * @channel_name: Channel name used in device tree. 118e13d7572SSiddartha Mohanadoss */ 119e13d7572SSiddartha Mohanadoss struct adc5_channel_prop { 120e13d7572SSiddartha Mohanadoss unsigned int channel; 121e13d7572SSiddartha Mohanadoss enum adc5_cal_method cal_method; 122e13d7572SSiddartha Mohanadoss enum adc5_cal_val cal_val; 123e13d7572SSiddartha Mohanadoss unsigned int decimation; 124082111e5SJishnu Prakash unsigned int sid; 125e13d7572SSiddartha Mohanadoss unsigned int prescale; 126e13d7572SSiddartha Mohanadoss unsigned int hw_settle_time; 127e13d7572SSiddartha Mohanadoss unsigned int avg_samples; 128e13d7572SSiddartha Mohanadoss enum vadc_scale_fn_type scale_fn_type; 129e93cde03SMarijn Suijten const char *channel_name; 130e13d7572SSiddartha Mohanadoss }; 131e13d7572SSiddartha Mohanadoss 132e13d7572SSiddartha Mohanadoss /** 133e13d7572SSiddartha Mohanadoss * struct adc5_chip - ADC private structure. 134e13d7572SSiddartha Mohanadoss * @regmap: SPMI ADC5 peripheral register map field. 135e13d7572SSiddartha Mohanadoss * @dev: SPMI ADC5 device. 136e13d7572SSiddartha Mohanadoss * @base: base address for the ADC peripheral. 137e13d7572SSiddartha Mohanadoss * @nchannels: number of ADC channels. 138e13d7572SSiddartha Mohanadoss * @chan_props: array of ADC channel properties. 139e13d7572SSiddartha Mohanadoss * @iio_chans: array of IIO channels specification. 140e13d7572SSiddartha Mohanadoss * @poll_eoc: use polling instead of interrupt. 141e13d7572SSiddartha Mohanadoss * @complete: ADC result notification after interrupt is received. 142e13d7572SSiddartha Mohanadoss * @lock: ADC lock for access to the peripheral. 143e13d7572SSiddartha Mohanadoss * @data: software configuration data. 144e13d7572SSiddartha Mohanadoss */ 145e13d7572SSiddartha Mohanadoss struct adc5_chip { 146e13d7572SSiddartha Mohanadoss struct regmap *regmap; 147e13d7572SSiddartha Mohanadoss struct device *dev; 148e13d7572SSiddartha Mohanadoss u16 base; 149e13d7572SSiddartha Mohanadoss unsigned int nchannels; 150e13d7572SSiddartha Mohanadoss struct adc5_channel_prop *chan_props; 151e13d7572SSiddartha Mohanadoss struct iio_chan_spec *iio_chans; 152e13d7572SSiddartha Mohanadoss bool poll_eoc; 153e13d7572SSiddartha Mohanadoss struct completion complete; 154e13d7572SSiddartha Mohanadoss struct mutex lock; 155e13d7572SSiddartha Mohanadoss const struct adc5_data *data; 156e13d7572SSiddartha Mohanadoss }; 157e13d7572SSiddartha Mohanadoss 158e13d7572SSiddartha Mohanadoss static int adc5_read(struct adc5_chip *adc, u16 offset, u8 *data, int len) 159e13d7572SSiddartha Mohanadoss { 160e13d7572SSiddartha Mohanadoss return regmap_bulk_read(adc->regmap, adc->base + offset, data, len); 161e13d7572SSiddartha Mohanadoss } 162e13d7572SSiddartha Mohanadoss 163e13d7572SSiddartha Mohanadoss static int adc5_write(struct adc5_chip *adc, u16 offset, u8 *data, int len) 164e13d7572SSiddartha Mohanadoss { 165e13d7572SSiddartha Mohanadoss return regmap_bulk_write(adc->regmap, adc->base + offset, data, len); 166e13d7572SSiddartha Mohanadoss } 167e13d7572SSiddartha Mohanadoss 168082111e5SJishnu Prakash static int adc5_masked_write(struct adc5_chip *adc, u16 offset, u8 mask, u8 val) 169082111e5SJishnu Prakash { 170082111e5SJishnu Prakash return regmap_update_bits(adc->regmap, adc->base + offset, mask, val); 171082111e5SJishnu Prakash } 172082111e5SJishnu Prakash 173e13d7572SSiddartha Mohanadoss static int adc5_read_voltage_data(struct adc5_chip *adc, u16 *data) 174e13d7572SSiddartha Mohanadoss { 175e13d7572SSiddartha Mohanadoss int ret; 176e13d7572SSiddartha Mohanadoss u8 rslt_lsb, rslt_msb; 177e13d7572SSiddartha Mohanadoss 178e13d7572SSiddartha Mohanadoss ret = adc5_read(adc, ADC5_USR_DATA0, &rslt_lsb, sizeof(rslt_lsb)); 179e13d7572SSiddartha Mohanadoss if (ret) 180e13d7572SSiddartha Mohanadoss return ret; 181e13d7572SSiddartha Mohanadoss 182e13d7572SSiddartha Mohanadoss ret = adc5_read(adc, ADC5_USR_DATA1, &rslt_msb, sizeof(rslt_lsb)); 183e13d7572SSiddartha Mohanadoss if (ret) 184e13d7572SSiddartha Mohanadoss return ret; 185e13d7572SSiddartha Mohanadoss 186e13d7572SSiddartha Mohanadoss *data = (rslt_msb << 8) | rslt_lsb; 187e13d7572SSiddartha Mohanadoss 188e13d7572SSiddartha Mohanadoss if (*data == ADC5_USR_DATA_CHECK) { 189603375dfSJishnu Prakash dev_err(adc->dev, "Invalid data:0x%x\n", *data); 190e13d7572SSiddartha Mohanadoss return -EINVAL; 191e13d7572SSiddartha Mohanadoss } 192e13d7572SSiddartha Mohanadoss 193603375dfSJishnu Prakash dev_dbg(adc->dev, "voltage raw code:0x%x\n", *data); 194e13d7572SSiddartha Mohanadoss 195e13d7572SSiddartha Mohanadoss return 0; 196e13d7572SSiddartha Mohanadoss } 197e13d7572SSiddartha Mohanadoss 198e13d7572SSiddartha Mohanadoss static int adc5_poll_wait_eoc(struct adc5_chip *adc) 199e13d7572SSiddartha Mohanadoss { 200e13d7572SSiddartha Mohanadoss unsigned int count, retry = ADC5_CONV_TIME_RETRY; 201e13d7572SSiddartha Mohanadoss u8 status1; 202e13d7572SSiddartha Mohanadoss int ret; 203e13d7572SSiddartha Mohanadoss 204e13d7572SSiddartha Mohanadoss for (count = 0; count < retry; count++) { 205e13d7572SSiddartha Mohanadoss ret = adc5_read(adc, ADC5_USR_STATUS1, &status1, 206e13d7572SSiddartha Mohanadoss sizeof(status1)); 207e13d7572SSiddartha Mohanadoss if (ret) 208e13d7572SSiddartha Mohanadoss return ret; 209e13d7572SSiddartha Mohanadoss 210e13d7572SSiddartha Mohanadoss status1 &= ADC5_USR_STATUS1_REQ_STS_EOC_MASK; 211e13d7572SSiddartha Mohanadoss if (status1 == ADC5_USR_STATUS1_EOC) 212e13d7572SSiddartha Mohanadoss return 0; 213e13d7572SSiddartha Mohanadoss 214e13d7572SSiddartha Mohanadoss usleep_range(ADC5_CONV_TIME_MIN_US, ADC5_CONV_TIME_MAX_US); 215e13d7572SSiddartha Mohanadoss } 216e13d7572SSiddartha Mohanadoss 217e13d7572SSiddartha Mohanadoss return -ETIMEDOUT; 218e13d7572SSiddartha Mohanadoss } 219e13d7572SSiddartha Mohanadoss 220e13d7572SSiddartha Mohanadoss static void adc5_update_dig_param(struct adc5_chip *adc, 221e13d7572SSiddartha Mohanadoss struct adc5_channel_prop *prop, u8 *data) 222e13d7572SSiddartha Mohanadoss { 223e13d7572SSiddartha Mohanadoss /* Update calibration value */ 224e13d7572SSiddartha Mohanadoss *data &= ~ADC5_USR_DIG_PARAM_CAL_VAL; 225e13d7572SSiddartha Mohanadoss *data |= (prop->cal_val << ADC5_USR_DIG_PARAM_CAL_VAL_SHIFT); 226e13d7572SSiddartha Mohanadoss 227e13d7572SSiddartha Mohanadoss /* Update calibration select */ 228e13d7572SSiddartha Mohanadoss *data &= ~ADC5_USR_DIG_PARAM_CAL_SEL; 229e13d7572SSiddartha Mohanadoss *data |= (prop->cal_method << ADC5_USR_DIG_PARAM_CAL_SEL_SHIFT); 230e13d7572SSiddartha Mohanadoss 231e13d7572SSiddartha Mohanadoss /* Update decimation ratio select */ 232e13d7572SSiddartha Mohanadoss *data &= ~ADC5_USR_DIG_PARAM_DEC_RATIO_SEL; 233e13d7572SSiddartha Mohanadoss *data |= (prop->decimation << ADC5_USR_DIG_PARAM_DEC_RATIO_SEL_SHIFT); 234e13d7572SSiddartha Mohanadoss } 235e13d7572SSiddartha Mohanadoss 236e13d7572SSiddartha Mohanadoss static int adc5_configure(struct adc5_chip *adc, 237e13d7572SSiddartha Mohanadoss struct adc5_channel_prop *prop) 238e13d7572SSiddartha Mohanadoss { 239e13d7572SSiddartha Mohanadoss int ret; 240e13d7572SSiddartha Mohanadoss u8 buf[6]; 241e13d7572SSiddartha Mohanadoss 242e13d7572SSiddartha Mohanadoss /* Read registers 0x42 through 0x46 */ 243e13d7572SSiddartha Mohanadoss ret = adc5_read(adc, ADC5_USR_DIG_PARAM, buf, sizeof(buf)); 24435fbb7f0SJishnu Prakash if (ret) 245e13d7572SSiddartha Mohanadoss return ret; 246e13d7572SSiddartha Mohanadoss 247e13d7572SSiddartha Mohanadoss /* Digital param selection */ 248e13d7572SSiddartha Mohanadoss adc5_update_dig_param(adc, prop, &buf[0]); 249e13d7572SSiddartha Mohanadoss 250e13d7572SSiddartha Mohanadoss /* Update fast average sample value */ 251e13d7572SSiddartha Mohanadoss buf[1] &= (u8) ~ADC5_USR_FAST_AVG_CTL_SAMPLES_MASK; 252e13d7572SSiddartha Mohanadoss buf[1] |= prop->avg_samples; 253e13d7572SSiddartha Mohanadoss 254e13d7572SSiddartha Mohanadoss /* Select ADC channel */ 255e13d7572SSiddartha Mohanadoss buf[2] = prop->channel; 256e13d7572SSiddartha Mohanadoss 257e13d7572SSiddartha Mohanadoss /* Select HW settle delay for channel */ 258e13d7572SSiddartha Mohanadoss buf[3] &= (u8) ~ADC5_USR_HW_SETTLE_DELAY_MASK; 259e13d7572SSiddartha Mohanadoss buf[3] |= prop->hw_settle_time; 260e13d7572SSiddartha Mohanadoss 261e13d7572SSiddartha Mohanadoss /* Select ADC enable */ 262e13d7572SSiddartha Mohanadoss buf[4] |= ADC5_USR_EN_CTL1_ADC_EN; 263e13d7572SSiddartha Mohanadoss 264e13d7572SSiddartha Mohanadoss /* Select CONV request */ 265e13d7572SSiddartha Mohanadoss buf[5] |= ADC5_USR_CONV_REQ_REQ; 266e13d7572SSiddartha Mohanadoss 267e13d7572SSiddartha Mohanadoss if (!adc->poll_eoc) 268e13d7572SSiddartha Mohanadoss reinit_completion(&adc->complete); 269e13d7572SSiddartha Mohanadoss 270e13d7572SSiddartha Mohanadoss return adc5_write(adc, ADC5_USR_DIG_PARAM, buf, sizeof(buf)); 271e13d7572SSiddartha Mohanadoss } 272e13d7572SSiddartha Mohanadoss 273082111e5SJishnu Prakash static int adc7_configure(struct adc5_chip *adc, 274082111e5SJishnu Prakash struct adc5_channel_prop *prop) 275082111e5SJishnu Prakash { 276082111e5SJishnu Prakash int ret; 277082111e5SJishnu Prakash u8 conv_req = 0, buf[4]; 278082111e5SJishnu Prakash 279082111e5SJishnu Prakash ret = adc5_masked_write(adc, ADC_APP_SID, ADC_APP_SID_MASK, prop->sid); 280082111e5SJishnu Prakash if (ret) 281082111e5SJishnu Prakash return ret; 282082111e5SJishnu Prakash 283082111e5SJishnu Prakash ret = adc5_read(adc, ADC5_USR_DIG_PARAM, buf, sizeof(buf)); 284082111e5SJishnu Prakash if (ret) 285082111e5SJishnu Prakash return ret; 286082111e5SJishnu Prakash 287082111e5SJishnu Prakash /* Digital param selection */ 288082111e5SJishnu Prakash adc5_update_dig_param(adc, prop, &buf[0]); 289082111e5SJishnu Prakash 290082111e5SJishnu Prakash /* Update fast average sample value */ 291082111e5SJishnu Prakash buf[1] &= ~ADC5_USR_FAST_AVG_CTL_SAMPLES_MASK; 292082111e5SJishnu Prakash buf[1] |= prop->avg_samples; 293082111e5SJishnu Prakash 294082111e5SJishnu Prakash /* Select ADC channel */ 295082111e5SJishnu Prakash buf[2] = prop->channel; 296082111e5SJishnu Prakash 297082111e5SJishnu Prakash /* Select HW settle delay for channel */ 298082111e5SJishnu Prakash buf[3] &= ~ADC5_USR_HW_SETTLE_DELAY_MASK; 299082111e5SJishnu Prakash buf[3] |= prop->hw_settle_time; 300082111e5SJishnu Prakash 301082111e5SJishnu Prakash /* Select CONV request */ 302082111e5SJishnu Prakash conv_req = ADC5_USR_CONV_REQ_REQ; 303082111e5SJishnu Prakash 304082111e5SJishnu Prakash if (!adc->poll_eoc) 305082111e5SJishnu Prakash reinit_completion(&adc->complete); 306082111e5SJishnu Prakash 307082111e5SJishnu Prakash ret = adc5_write(adc, ADC5_USR_DIG_PARAM, buf, sizeof(buf)); 308082111e5SJishnu Prakash if (ret) 309082111e5SJishnu Prakash return ret; 310082111e5SJishnu Prakash 311082111e5SJishnu Prakash return adc5_write(adc, ADC5_USR_CONV_REQ, &conv_req, 1); 312082111e5SJishnu Prakash } 313082111e5SJishnu Prakash 314e13d7572SSiddartha Mohanadoss static int adc5_do_conversion(struct adc5_chip *adc, 315e13d7572SSiddartha Mohanadoss struct adc5_channel_prop *prop, 316e13d7572SSiddartha Mohanadoss struct iio_chan_spec const *chan, 317e13d7572SSiddartha Mohanadoss u16 *data_volt, u16 *data_cur) 318e13d7572SSiddartha Mohanadoss { 319e13d7572SSiddartha Mohanadoss int ret; 320e13d7572SSiddartha Mohanadoss 321e13d7572SSiddartha Mohanadoss mutex_lock(&adc->lock); 322e13d7572SSiddartha Mohanadoss 323e13d7572SSiddartha Mohanadoss ret = adc5_configure(adc, prop); 324e13d7572SSiddartha Mohanadoss if (ret) { 325603375dfSJishnu Prakash dev_err(adc->dev, "ADC configure failed with %d\n", ret); 326e13d7572SSiddartha Mohanadoss goto unlock; 327e13d7572SSiddartha Mohanadoss } 328e13d7572SSiddartha Mohanadoss 329e13d7572SSiddartha Mohanadoss if (adc->poll_eoc) { 330e13d7572SSiddartha Mohanadoss ret = adc5_poll_wait_eoc(adc); 33135fbb7f0SJishnu Prakash if (ret) { 332603375dfSJishnu Prakash dev_err(adc->dev, "EOC bit not set\n"); 333e13d7572SSiddartha Mohanadoss goto unlock; 334e13d7572SSiddartha Mohanadoss } 335e13d7572SSiddartha Mohanadoss } else { 336e13d7572SSiddartha Mohanadoss ret = wait_for_completion_timeout(&adc->complete, 337e13d7572SSiddartha Mohanadoss ADC5_CONV_TIMEOUT); 338e13d7572SSiddartha Mohanadoss if (!ret) { 339603375dfSJishnu Prakash dev_dbg(adc->dev, "Did not get completion timeout.\n"); 340e13d7572SSiddartha Mohanadoss ret = adc5_poll_wait_eoc(adc); 34135fbb7f0SJishnu Prakash if (ret) { 342603375dfSJishnu Prakash dev_err(adc->dev, "EOC bit not set\n"); 343e13d7572SSiddartha Mohanadoss goto unlock; 344e13d7572SSiddartha Mohanadoss } 345e13d7572SSiddartha Mohanadoss } 346e13d7572SSiddartha Mohanadoss } 347e13d7572SSiddartha Mohanadoss 348e13d7572SSiddartha Mohanadoss ret = adc5_read_voltage_data(adc, data_volt); 349e13d7572SSiddartha Mohanadoss unlock: 350e13d7572SSiddartha Mohanadoss mutex_unlock(&adc->lock); 351e13d7572SSiddartha Mohanadoss 352e13d7572SSiddartha Mohanadoss return ret; 353e13d7572SSiddartha Mohanadoss } 354e13d7572SSiddartha Mohanadoss 355082111e5SJishnu Prakash static int adc7_do_conversion(struct adc5_chip *adc, 356082111e5SJishnu Prakash struct adc5_channel_prop *prop, 357082111e5SJishnu Prakash struct iio_chan_spec const *chan, 358082111e5SJishnu Prakash u16 *data_volt, u16 *data_cur) 359082111e5SJishnu Prakash { 360082111e5SJishnu Prakash int ret; 361082111e5SJishnu Prakash u8 status; 362082111e5SJishnu Prakash 363082111e5SJishnu Prakash mutex_lock(&adc->lock); 364082111e5SJishnu Prakash 365082111e5SJishnu Prakash ret = adc7_configure(adc, prop); 366082111e5SJishnu Prakash if (ret) { 367082111e5SJishnu Prakash dev_err(adc->dev, "ADC configure failed with %d\n", ret); 368082111e5SJishnu Prakash goto unlock; 369082111e5SJishnu Prakash } 370082111e5SJishnu Prakash 371082111e5SJishnu Prakash /* No support for polling mode at present */ 372082111e5SJishnu Prakash wait_for_completion_timeout(&adc->complete, ADC7_CONV_TIMEOUT); 373082111e5SJishnu Prakash 374082111e5SJishnu Prakash ret = adc5_read(adc, ADC5_USR_STATUS1, &status, 1); 375082111e5SJishnu Prakash if (ret) 376082111e5SJishnu Prakash goto unlock; 377082111e5SJishnu Prakash 378082111e5SJishnu Prakash if (status & ADC5_USR_STATUS1_CONV_FAULT) { 379082111e5SJishnu Prakash dev_err(adc->dev, "Unexpected conversion fault\n"); 380082111e5SJishnu Prakash ret = -EIO; 381082111e5SJishnu Prakash goto unlock; 382082111e5SJishnu Prakash } 383082111e5SJishnu Prakash 384082111e5SJishnu Prakash ret = adc5_read_voltage_data(adc, data_volt); 385082111e5SJishnu Prakash 386082111e5SJishnu Prakash unlock: 387082111e5SJishnu Prakash mutex_unlock(&adc->lock); 388082111e5SJishnu Prakash 389082111e5SJishnu Prakash return ret; 390082111e5SJishnu Prakash } 391082111e5SJishnu Prakash 3928f52a15aSJishnu Prakash typedef int (*adc_do_conversion)(struct adc5_chip *adc, 3938f52a15aSJishnu Prakash struct adc5_channel_prop *prop, 3948f52a15aSJishnu Prakash struct iio_chan_spec const *chan, 3958f52a15aSJishnu Prakash u16 *data_volt, u16 *data_cur); 3968f52a15aSJishnu Prakash 397e13d7572SSiddartha Mohanadoss static irqreturn_t adc5_isr(int irq, void *dev_id) 398e13d7572SSiddartha Mohanadoss { 399e13d7572SSiddartha Mohanadoss struct adc5_chip *adc = dev_id; 400e13d7572SSiddartha Mohanadoss 401e13d7572SSiddartha Mohanadoss complete(&adc->complete); 402e13d7572SSiddartha Mohanadoss 403e13d7572SSiddartha Mohanadoss return IRQ_HANDLED; 404e13d7572SSiddartha Mohanadoss } 405e13d7572SSiddartha Mohanadoss 4064f47a236SNuno Sá static int adc5_fwnode_xlate(struct iio_dev *indio_dev, 4074f47a236SNuno Sá const struct fwnode_reference_args *iiospec) 408e13d7572SSiddartha Mohanadoss { 409e13d7572SSiddartha Mohanadoss struct adc5_chip *adc = iio_priv(indio_dev); 410e13d7572SSiddartha Mohanadoss int i; 411e13d7572SSiddartha Mohanadoss 412e13d7572SSiddartha Mohanadoss for (i = 0; i < adc->nchannels; i++) 413e13d7572SSiddartha Mohanadoss if (adc->chan_props[i].channel == iiospec->args[0]) 414e13d7572SSiddartha Mohanadoss return i; 415e13d7572SSiddartha Mohanadoss 416e13d7572SSiddartha Mohanadoss return -EINVAL; 417e13d7572SSiddartha Mohanadoss } 418e13d7572SSiddartha Mohanadoss 4194f47a236SNuno Sá static int adc7_fwnode_xlate(struct iio_dev *indio_dev, 4204f47a236SNuno Sá const struct fwnode_reference_args *iiospec) 421082111e5SJishnu Prakash { 422082111e5SJishnu Prakash struct adc5_chip *adc = iio_priv(indio_dev); 423082111e5SJishnu Prakash int i, v_channel; 424082111e5SJishnu Prakash 425082111e5SJishnu Prakash for (i = 0; i < adc->nchannels; i++) { 426082111e5SJishnu Prakash v_channel = (adc->chan_props[i].sid << ADC_CHANNEL_OFFSET) | 427082111e5SJishnu Prakash adc->chan_props[i].channel; 428082111e5SJishnu Prakash if (v_channel == iiospec->args[0]) 429082111e5SJishnu Prakash return i; 430082111e5SJishnu Prakash } 431082111e5SJishnu Prakash 432082111e5SJishnu Prakash return -EINVAL; 433082111e5SJishnu Prakash } 434082111e5SJishnu Prakash 4358f52a15aSJishnu Prakash static int adc_read_raw_common(struct iio_dev *indio_dev, 436e13d7572SSiddartha Mohanadoss struct iio_chan_spec const *chan, int *val, int *val2, 4378f52a15aSJishnu Prakash long mask, adc_do_conversion do_conv) 438e13d7572SSiddartha Mohanadoss { 439e13d7572SSiddartha Mohanadoss struct adc5_chip *adc = iio_priv(indio_dev); 440e13d7572SSiddartha Mohanadoss struct adc5_channel_prop *prop; 441e13d7572SSiddartha Mohanadoss u16 adc_code_volt, adc_code_cur; 442e13d7572SSiddartha Mohanadoss int ret; 443e13d7572SSiddartha Mohanadoss 444e13d7572SSiddartha Mohanadoss prop = &adc->chan_props[chan->address]; 445e13d7572SSiddartha Mohanadoss 446e13d7572SSiddartha Mohanadoss switch (mask) { 447e13d7572SSiddartha Mohanadoss case IIO_CHAN_INFO_PROCESSED: 4488f52a15aSJishnu Prakash ret = do_conv(adc, prop, chan, 449e13d7572SSiddartha Mohanadoss &adc_code_volt, &adc_code_cur); 450e13d7572SSiddartha Mohanadoss if (ret) 451e13d7572SSiddartha Mohanadoss return ret; 452e13d7572SSiddartha Mohanadoss 453e13d7572SSiddartha Mohanadoss ret = qcom_adc5_hw_scale(prop->scale_fn_type, 454c7ba98fcSDmitry Baryshkov prop->prescale, 455e13d7572SSiddartha Mohanadoss adc->data, 456e13d7572SSiddartha Mohanadoss adc_code_volt, val); 457e13d7572SSiddartha Mohanadoss if (ret) 458e13d7572SSiddartha Mohanadoss return ret; 459e13d7572SSiddartha Mohanadoss 460e13d7572SSiddartha Mohanadoss return IIO_VAL_INT; 461e13d7572SSiddartha Mohanadoss default: 462e13d7572SSiddartha Mohanadoss return -EINVAL; 463e13d7572SSiddartha Mohanadoss } 464e13d7572SSiddartha Mohanadoss } 465e13d7572SSiddartha Mohanadoss 4668f52a15aSJishnu Prakash static int adc5_read_raw(struct iio_dev *indio_dev, 4678f52a15aSJishnu Prakash struct iio_chan_spec const *chan, int *val, int *val2, 4688f52a15aSJishnu Prakash long mask) 4698f52a15aSJishnu Prakash { 4708f52a15aSJishnu Prakash return adc_read_raw_common(indio_dev, chan, val, val2, 4718f52a15aSJishnu Prakash mask, adc5_do_conversion); 4728f52a15aSJishnu Prakash } 4738f52a15aSJishnu Prakash 474082111e5SJishnu Prakash static int adc7_read_raw(struct iio_dev *indio_dev, 475082111e5SJishnu Prakash struct iio_chan_spec const *chan, int *val, int *val2, 476082111e5SJishnu Prakash long mask) 477082111e5SJishnu Prakash { 4788f52a15aSJishnu Prakash return adc_read_raw_common(indio_dev, chan, val, val2, 4798f52a15aSJishnu Prakash mask, adc7_do_conversion); 480082111e5SJishnu Prakash } 481082111e5SJishnu Prakash 482e13d7572SSiddartha Mohanadoss static const struct iio_info adc5_info = { 483e13d7572SSiddartha Mohanadoss .read_raw = adc5_read_raw, 4844f47a236SNuno Sá .fwnode_xlate = adc5_fwnode_xlate, 485e13d7572SSiddartha Mohanadoss }; 486e13d7572SSiddartha Mohanadoss 487082111e5SJishnu Prakash static const struct iio_info adc7_info = { 488082111e5SJishnu Prakash .read_raw = adc7_read_raw, 4894f47a236SNuno Sá .fwnode_xlate = adc7_fwnode_xlate, 490082111e5SJishnu Prakash }; 491082111e5SJishnu Prakash 492e13d7572SSiddartha Mohanadoss struct adc5_channels { 493e13d7572SSiddartha Mohanadoss const char *datasheet_name; 494e13d7572SSiddartha Mohanadoss unsigned int prescale_index; 495e13d7572SSiddartha Mohanadoss enum iio_chan_type type; 496e13d7572SSiddartha Mohanadoss long info_mask; 497e13d7572SSiddartha Mohanadoss enum vadc_scale_fn_type scale_fn_type; 498e13d7572SSiddartha Mohanadoss }; 499e13d7572SSiddartha Mohanadoss 500db23d887SEvan Green /* In these definitions, _pre refers to an index into adc5_prescale_ratios. */ 501e13d7572SSiddartha Mohanadoss #define ADC5_CHAN(_dname, _type, _mask, _pre, _scale) \ 502e13d7572SSiddartha Mohanadoss { \ 503e13d7572SSiddartha Mohanadoss .datasheet_name = _dname, \ 504e13d7572SSiddartha Mohanadoss .prescale_index = _pre, \ 505e13d7572SSiddartha Mohanadoss .type = _type, \ 506e13d7572SSiddartha Mohanadoss .info_mask = _mask, \ 507e13d7572SSiddartha Mohanadoss .scale_fn_type = _scale, \ 508e13d7572SSiddartha Mohanadoss }, \ 509e13d7572SSiddartha Mohanadoss 510e13d7572SSiddartha Mohanadoss #define ADC5_CHAN_TEMP(_dname, _pre, _scale) \ 511e13d7572SSiddartha Mohanadoss ADC5_CHAN(_dname, IIO_TEMP, \ 512e13d7572SSiddartha Mohanadoss BIT(IIO_CHAN_INFO_PROCESSED), \ 513e13d7572SSiddartha Mohanadoss _pre, _scale) \ 514e13d7572SSiddartha Mohanadoss 515e13d7572SSiddartha Mohanadoss #define ADC5_CHAN_VOLT(_dname, _pre, _scale) \ 516e13d7572SSiddartha Mohanadoss ADC5_CHAN(_dname, IIO_VOLTAGE, \ 517e13d7572SSiddartha Mohanadoss BIT(IIO_CHAN_INFO_PROCESSED), \ 518e13d7572SSiddartha Mohanadoss _pre, _scale) \ 519e13d7572SSiddartha Mohanadoss 520e13d7572SSiddartha Mohanadoss static const struct adc5_channels adc5_chans_pmic[ADC5_MAX_CHANNEL] = { 521db23d887SEvan Green [ADC5_REF_GND] = ADC5_CHAN_VOLT("ref_gnd", 0, 522e13d7572SSiddartha Mohanadoss SCALE_HW_CALIB_DEFAULT) 523db23d887SEvan Green [ADC5_1P25VREF] = ADC5_CHAN_VOLT("vref_1p25", 0, 524e13d7572SSiddartha Mohanadoss SCALE_HW_CALIB_DEFAULT) 525db23d887SEvan Green [ADC5_VPH_PWR] = ADC5_CHAN_VOLT("vph_pwr", 1, 526e13d7572SSiddartha Mohanadoss SCALE_HW_CALIB_DEFAULT) 527db23d887SEvan Green [ADC5_VBAT_SNS] = ADC5_CHAN_VOLT("vbat_sns", 1, 528e13d7572SSiddartha Mohanadoss SCALE_HW_CALIB_DEFAULT) 52915b2ac67SMarijn Suijten [ADC5_VCOIN] = ADC5_CHAN_VOLT("vcoin", 1, 53015b2ac67SMarijn Suijten SCALE_HW_CALIB_DEFAULT) 531db23d887SEvan Green [ADC5_DIE_TEMP] = ADC5_CHAN_TEMP("die_temp", 0, 532e13d7572SSiddartha Mohanadoss SCALE_HW_CALIB_PMIC_THERM) 533db23d887SEvan Green [ADC5_USB_IN_I] = ADC5_CHAN_VOLT("usb_in_i_uv", 0, 534e13d7572SSiddartha Mohanadoss SCALE_HW_CALIB_DEFAULT) 535db23d887SEvan Green [ADC5_USB_IN_V_16] = ADC5_CHAN_VOLT("usb_in_v_div_16", 8, 536e13d7572SSiddartha Mohanadoss SCALE_HW_CALIB_DEFAULT) 537db23d887SEvan Green [ADC5_CHG_TEMP] = ADC5_CHAN_TEMP("chg_temp", 0, 538e13d7572SSiddartha Mohanadoss SCALE_HW_CALIB_PM5_CHG_TEMP) 539e13d7572SSiddartha Mohanadoss /* Charger prescales SBUx and MID_CHG to fit within 1.8V upper unit */ 540db23d887SEvan Green [ADC5_SBUx] = ADC5_CHAN_VOLT("chg_sbux", 1, 541e13d7572SSiddartha Mohanadoss SCALE_HW_CALIB_DEFAULT) 542db23d887SEvan Green [ADC5_MID_CHG_DIV6] = ADC5_CHAN_VOLT("chg_mid_chg", 3, 543e13d7572SSiddartha Mohanadoss SCALE_HW_CALIB_DEFAULT) 544db23d887SEvan Green [ADC5_XO_THERM_100K_PU] = ADC5_CHAN_TEMP("xo_therm", 0, 545e13d7572SSiddartha Mohanadoss SCALE_HW_CALIB_XOTHERM) 54614e5b7abSLuca Weiss [ADC5_BAT_ID_100K_PU] = ADC5_CHAN_TEMP("bat_id", 0, 54714e5b7abSLuca Weiss SCALE_HW_CALIB_DEFAULT) 548db23d887SEvan Green [ADC5_AMUX_THM1_100K_PU] = ADC5_CHAN_TEMP("amux_thm1_100k_pu", 0, 549e13d7572SSiddartha Mohanadoss SCALE_HW_CALIB_THERM_100K_PULLUP) 550db23d887SEvan Green [ADC5_AMUX_THM2_100K_PU] = ADC5_CHAN_TEMP("amux_thm2_100k_pu", 0, 551e13d7572SSiddartha Mohanadoss SCALE_HW_CALIB_THERM_100K_PULLUP) 552db23d887SEvan Green [ADC5_AMUX_THM3_100K_PU] = ADC5_CHAN_TEMP("amux_thm3_100k_pu", 0, 553e13d7572SSiddartha Mohanadoss SCALE_HW_CALIB_THERM_100K_PULLUP) 554db23d887SEvan Green [ADC5_AMUX_THM2] = ADC5_CHAN_TEMP("amux_thm2", 0, 555e13d7572SSiddartha Mohanadoss SCALE_HW_CALIB_PM5_SMB_TEMP) 55615b2ac67SMarijn Suijten [ADC5_GPIO1_100K_PU] = ADC5_CHAN_TEMP("gpio1_100k_pu", 0, 55715b2ac67SMarijn Suijten SCALE_HW_CALIB_THERM_100K_PULLUP) 55896543470SKonrad Dybcio [ADC5_GPIO2_100K_PU] = ADC5_CHAN_TEMP("gpio2_100k_pu", 0, 55996543470SKonrad Dybcio SCALE_HW_CALIB_THERM_100K_PULLUP) 56015b2ac67SMarijn Suijten [ADC5_GPIO3_100K_PU] = ADC5_CHAN_TEMP("gpio3_100k_pu", 0, 56115b2ac67SMarijn Suijten SCALE_HW_CALIB_THERM_100K_PULLUP) 56215b2ac67SMarijn Suijten [ADC5_GPIO4_100K_PU] = ADC5_CHAN_TEMP("gpio4_100k_pu", 0, 56315b2ac67SMarijn Suijten SCALE_HW_CALIB_THERM_100K_PULLUP) 564e13d7572SSiddartha Mohanadoss }; 565e13d7572SSiddartha Mohanadoss 566082111e5SJishnu Prakash static const struct adc5_channels adc7_chans_pmic[ADC5_MAX_CHANNEL] = { 567082111e5SJishnu Prakash [ADC7_REF_GND] = ADC5_CHAN_VOLT("ref_gnd", 0, 568082111e5SJishnu Prakash SCALE_HW_CALIB_DEFAULT) 569082111e5SJishnu Prakash [ADC7_1P25VREF] = ADC5_CHAN_VOLT("vref_1p25", 0, 570082111e5SJishnu Prakash SCALE_HW_CALIB_DEFAULT) 571082111e5SJishnu Prakash [ADC7_VPH_PWR] = ADC5_CHAN_VOLT("vph_pwr", 1, 572082111e5SJishnu Prakash SCALE_HW_CALIB_DEFAULT) 573082111e5SJishnu Prakash [ADC7_VBAT_SNS] = ADC5_CHAN_VOLT("vbat_sns", 3, 574082111e5SJishnu Prakash SCALE_HW_CALIB_DEFAULT) 575082111e5SJishnu Prakash [ADC7_DIE_TEMP] = ADC5_CHAN_TEMP("die_temp", 0, 576082111e5SJishnu Prakash SCALE_HW_CALIB_PMIC_THERM_PM7) 577082111e5SJishnu Prakash [ADC7_AMUX_THM1_100K_PU] = ADC5_CHAN_TEMP("amux_thm1_pu2", 0, 578082111e5SJishnu Prakash SCALE_HW_CALIB_THERM_100K_PU_PM7) 579082111e5SJishnu Prakash [ADC7_AMUX_THM2_100K_PU] = ADC5_CHAN_TEMP("amux_thm2_pu2", 0, 580082111e5SJishnu Prakash SCALE_HW_CALIB_THERM_100K_PU_PM7) 581082111e5SJishnu Prakash [ADC7_AMUX_THM3_100K_PU] = ADC5_CHAN_TEMP("amux_thm3_pu2", 0, 582082111e5SJishnu Prakash SCALE_HW_CALIB_THERM_100K_PU_PM7) 583082111e5SJishnu Prakash [ADC7_AMUX_THM4_100K_PU] = ADC5_CHAN_TEMP("amux_thm4_pu2", 0, 584082111e5SJishnu Prakash SCALE_HW_CALIB_THERM_100K_PU_PM7) 585082111e5SJishnu Prakash [ADC7_AMUX_THM5_100K_PU] = ADC5_CHAN_TEMP("amux_thm5_pu2", 0, 586082111e5SJishnu Prakash SCALE_HW_CALIB_THERM_100K_PU_PM7) 587082111e5SJishnu Prakash [ADC7_AMUX_THM6_100K_PU] = ADC5_CHAN_TEMP("amux_thm6_pu2", 0, 588082111e5SJishnu Prakash SCALE_HW_CALIB_THERM_100K_PU_PM7) 589082111e5SJishnu Prakash [ADC7_GPIO1_100K_PU] = ADC5_CHAN_TEMP("gpio1_pu2", 0, 590082111e5SJishnu Prakash SCALE_HW_CALIB_THERM_100K_PU_PM7) 591082111e5SJishnu Prakash [ADC7_GPIO2_100K_PU] = ADC5_CHAN_TEMP("gpio2_pu2", 0, 592082111e5SJishnu Prakash SCALE_HW_CALIB_THERM_100K_PU_PM7) 593082111e5SJishnu Prakash [ADC7_GPIO3_100K_PU] = ADC5_CHAN_TEMP("gpio3_pu2", 0, 594082111e5SJishnu Prakash SCALE_HW_CALIB_THERM_100K_PU_PM7) 595082111e5SJishnu Prakash [ADC7_GPIO4_100K_PU] = ADC5_CHAN_TEMP("gpio4_pu2", 0, 596082111e5SJishnu Prakash SCALE_HW_CALIB_THERM_100K_PU_PM7) 597082111e5SJishnu Prakash }; 598082111e5SJishnu Prakash 599e13d7572SSiddartha Mohanadoss static const struct adc5_channels adc5_chans_rev2[ADC5_MAX_CHANNEL] = { 600db23d887SEvan Green [ADC5_REF_GND] = ADC5_CHAN_VOLT("ref_gnd", 0, 601e13d7572SSiddartha Mohanadoss SCALE_HW_CALIB_DEFAULT) 602db23d887SEvan Green [ADC5_1P25VREF] = ADC5_CHAN_VOLT("vref_1p25", 0, 603e13d7572SSiddartha Mohanadoss SCALE_HW_CALIB_DEFAULT) 60483de8060SRobert Marko [ADC5_VREF_VADC] = ADC5_CHAN_VOLT("vref_vadc", 0, 60583de8060SRobert Marko SCALE_HW_CALIB_DEFAULT) 606db23d887SEvan Green [ADC5_VPH_PWR] = ADC5_CHAN_VOLT("vph_pwr", 1, 607e13d7572SSiddartha Mohanadoss SCALE_HW_CALIB_DEFAULT) 608db23d887SEvan Green [ADC5_VBAT_SNS] = ADC5_CHAN_VOLT("vbat_sns", 1, 609e13d7572SSiddartha Mohanadoss SCALE_HW_CALIB_DEFAULT) 610db23d887SEvan Green [ADC5_VCOIN] = ADC5_CHAN_VOLT("vcoin", 1, 611e13d7572SSiddartha Mohanadoss SCALE_HW_CALIB_DEFAULT) 612db23d887SEvan Green [ADC5_DIE_TEMP] = ADC5_CHAN_TEMP("die_temp", 0, 613e13d7572SSiddartha Mohanadoss SCALE_HW_CALIB_PMIC_THERM) 614db23d887SEvan Green [ADC5_AMUX_THM1_100K_PU] = ADC5_CHAN_TEMP("amux_thm1_100k_pu", 0, 615e13d7572SSiddartha Mohanadoss SCALE_HW_CALIB_THERM_100K_PULLUP) 616db23d887SEvan Green [ADC5_AMUX_THM2_100K_PU] = ADC5_CHAN_TEMP("amux_thm2_100k_pu", 0, 6174d0434f1SMatthias Kaehlcke SCALE_HW_CALIB_THERM_100K_PULLUP) 618db23d887SEvan Green [ADC5_AMUX_THM3_100K_PU] = ADC5_CHAN_TEMP("amux_thm3_100k_pu", 0, 619e13d7572SSiddartha Mohanadoss SCALE_HW_CALIB_THERM_100K_PULLUP) 620db23d887SEvan Green [ADC5_AMUX_THM4_100K_PU] = ADC5_CHAN_TEMP("amux_thm4_100k_pu", 0, 6214d0434f1SMatthias Kaehlcke SCALE_HW_CALIB_THERM_100K_PULLUP) 622db23d887SEvan Green [ADC5_AMUX_THM5_100K_PU] = ADC5_CHAN_TEMP("amux_thm5_100k_pu", 0, 623e13d7572SSiddartha Mohanadoss SCALE_HW_CALIB_THERM_100K_PULLUP) 624db23d887SEvan Green [ADC5_XO_THERM_100K_PU] = ADC5_CHAN_TEMP("xo_therm_100k_pu", 0, 625e13d7572SSiddartha Mohanadoss SCALE_HW_CALIB_THERM_100K_PULLUP) 626e13d7572SSiddartha Mohanadoss }; 627e13d7572SSiddartha Mohanadoss 6284f47a236SNuno Sá static int adc5_get_fw_channel_data(struct adc5_chip *adc, 629e13d7572SSiddartha Mohanadoss struct adc5_channel_prop *prop, 6304f47a236SNuno Sá struct fwnode_handle *fwnode, 631e13d7572SSiddartha Mohanadoss const struct adc5_data *data) 632e13d7572SSiddartha Mohanadoss { 633701c875aSAndy Shevchenko const char *channel_name; 634701c875aSAndy Shevchenko char *name; 635e13d7572SSiddartha Mohanadoss u32 chan, value, varr[2]; 636082111e5SJishnu Prakash u32 sid = 0; 637e13d7572SSiddartha Mohanadoss int ret; 638e13d7572SSiddartha Mohanadoss struct device *dev = adc->dev; 639e13d7572SSiddartha Mohanadoss 640701c875aSAndy Shevchenko name = devm_kasprintf(dev, GFP_KERNEL, "%pfwP", fwnode); 641701c875aSAndy Shevchenko if (!name) 642701c875aSAndy Shevchenko return -ENOMEM; 643701c875aSAndy Shevchenko 644701c875aSAndy Shevchenko /* Cut the address part */ 645701c875aSAndy Shevchenko name[strchrnul(name, '@') - name] = '\0'; 646701c875aSAndy Shevchenko 6474f47a236SNuno Sá ret = fwnode_property_read_u32(fwnode, "reg", &chan); 648e13d7572SSiddartha Mohanadoss if (ret) { 649e13d7572SSiddartha Mohanadoss dev_err(dev, "invalid channel number %s\n", name); 650e13d7572SSiddartha Mohanadoss return ret; 651e13d7572SSiddartha Mohanadoss } 652e13d7572SSiddartha Mohanadoss 653082111e5SJishnu Prakash /* Value read from "reg" is virtual channel number */ 654082111e5SJishnu Prakash 655082111e5SJishnu Prakash /* virtual channel number = sid << 8 | channel number */ 656082111e5SJishnu Prakash 657082111e5SJishnu Prakash if (adc->data->info == &adc7_info) { 658082111e5SJishnu Prakash sid = chan >> ADC_CHANNEL_OFFSET; 659082111e5SJishnu Prakash chan = chan & ADC_CHANNEL_MASK; 660082111e5SJishnu Prakash } 661082111e5SJishnu Prakash 662ac0abf75SMarijn Suijten if (chan > ADC5_PARALLEL_ISENSE_VBAT_IDATA) { 663e13d7572SSiddartha Mohanadoss dev_err(dev, "%s invalid channel number %d\n", name, chan); 664e13d7572SSiddartha Mohanadoss return -EINVAL; 665e13d7572SSiddartha Mohanadoss } 666e13d7572SSiddartha Mohanadoss 667e13d7572SSiddartha Mohanadoss /* the channel has DT description */ 668e13d7572SSiddartha Mohanadoss prop->channel = chan; 669082111e5SJishnu Prakash prop->sid = sid; 670e13d7572SSiddartha Mohanadoss 6714f47a236SNuno Sá ret = fwnode_property_read_string(fwnode, "label", &channel_name); 6724f47a236SNuno Sá if (ret) 6730744ef3bSMarijn Suijten channel_name = data->adc_chans[chan].datasheet_name; 6744f47a236SNuno Sá 675e93cde03SMarijn Suijten prop->channel_name = channel_name; 676e13d7572SSiddartha Mohanadoss 6774f47a236SNuno Sá ret = fwnode_property_read_u32(fwnode, "qcom,decimation", &value); 678e13d7572SSiddartha Mohanadoss if (!ret) { 679c7ba98fcSDmitry Baryshkov ret = qcom_adc5_decimation_from_dt(value, data->decimation); 680e13d7572SSiddartha Mohanadoss if (ret < 0) { 681e13d7572SSiddartha Mohanadoss dev_err(dev, "%02x invalid decimation %d\n", 682e13d7572SSiddartha Mohanadoss chan, value); 683e13d7572SSiddartha Mohanadoss return ret; 684e13d7572SSiddartha Mohanadoss } 685e13d7572SSiddartha Mohanadoss prop->decimation = ret; 686e13d7572SSiddartha Mohanadoss } else { 687e13d7572SSiddartha Mohanadoss prop->decimation = ADC5_DECIMATION_DEFAULT; 688e13d7572SSiddartha Mohanadoss } 689e13d7572SSiddartha Mohanadoss 6904f47a236SNuno Sá ret = fwnode_property_read_u32_array(fwnode, "qcom,pre-scaling", varr, 2); 691e13d7572SSiddartha Mohanadoss if (!ret) { 692c7ba98fcSDmitry Baryshkov ret = qcom_adc5_prescaling_from_dt(varr[0], varr[1]); 693e13d7572SSiddartha Mohanadoss if (ret < 0) { 694e13d7572SSiddartha Mohanadoss dev_err(dev, "%02x invalid pre-scaling <%d %d>\n", 695e13d7572SSiddartha Mohanadoss chan, varr[0], varr[1]); 696e13d7572SSiddartha Mohanadoss return ret; 697e13d7572SSiddartha Mohanadoss } 698e13d7572SSiddartha Mohanadoss prop->prescale = ret; 699db23d887SEvan Green } else { 700db23d887SEvan Green prop->prescale = 701db23d887SEvan Green adc->data->adc_chans[prop->channel].prescale_index; 702e13d7572SSiddartha Mohanadoss } 703e13d7572SSiddartha Mohanadoss 7044f47a236SNuno Sá ret = fwnode_property_read_u32(fwnode, "qcom,hw-settle-time", &value); 705e13d7572SSiddartha Mohanadoss if (!ret) { 706e13d7572SSiddartha Mohanadoss u8 dig_version[2]; 707e13d7572SSiddartha Mohanadoss 708e13d7572SSiddartha Mohanadoss ret = adc5_read(adc, ADC5_USR_REVISION1, dig_version, 709e13d7572SSiddartha Mohanadoss sizeof(dig_version)); 71035fbb7f0SJishnu Prakash if (ret) { 711e13d7572SSiddartha Mohanadoss dev_err(dev, "Invalid dig version read %d\n", ret); 712e13d7572SSiddartha Mohanadoss return ret; 713e13d7572SSiddartha Mohanadoss } 714e13d7572SSiddartha Mohanadoss 715603375dfSJishnu Prakash dev_dbg(dev, "dig_ver:minor:%d, major:%d\n", dig_version[0], 716e13d7572SSiddartha Mohanadoss dig_version[1]); 717e13d7572SSiddartha Mohanadoss /* Digital controller >= 5.3 have hw_settle_2 option */ 718082111e5SJishnu Prakash if ((dig_version[0] >= ADC5_HW_SETTLE_DIFF_MINOR && 719082111e5SJishnu Prakash dig_version[1] >= ADC5_HW_SETTLE_DIFF_MAJOR) || 720082111e5SJishnu Prakash adc->data->info == &adc7_info) 721c7ba98fcSDmitry Baryshkov ret = qcom_adc5_hw_settle_time_from_dt(value, data->hw_settle_2); 722e13d7572SSiddartha Mohanadoss else 723c7ba98fcSDmitry Baryshkov ret = qcom_adc5_hw_settle_time_from_dt(value, data->hw_settle_1); 724e13d7572SSiddartha Mohanadoss 725e13d7572SSiddartha Mohanadoss if (ret < 0) { 726e13d7572SSiddartha Mohanadoss dev_err(dev, "%02x invalid hw-settle-time %d us\n", 727e13d7572SSiddartha Mohanadoss chan, value); 728e13d7572SSiddartha Mohanadoss return ret; 729e13d7572SSiddartha Mohanadoss } 730e13d7572SSiddartha Mohanadoss prop->hw_settle_time = ret; 731e13d7572SSiddartha Mohanadoss } else { 732e13d7572SSiddartha Mohanadoss prop->hw_settle_time = VADC_DEF_HW_SETTLE_TIME; 733e13d7572SSiddartha Mohanadoss } 734e13d7572SSiddartha Mohanadoss 7354f47a236SNuno Sá ret = fwnode_property_read_u32(fwnode, "qcom,avg-samples", &value); 736e13d7572SSiddartha Mohanadoss if (!ret) { 737c7ba98fcSDmitry Baryshkov ret = qcom_adc5_avg_samples_from_dt(value); 738e13d7572SSiddartha Mohanadoss if (ret < 0) { 739e13d7572SSiddartha Mohanadoss dev_err(dev, "%02x invalid avg-samples %d\n", 740e13d7572SSiddartha Mohanadoss chan, value); 741e13d7572SSiddartha Mohanadoss return ret; 742e13d7572SSiddartha Mohanadoss } 743e13d7572SSiddartha Mohanadoss prop->avg_samples = ret; 744e13d7572SSiddartha Mohanadoss } else { 745e13d7572SSiddartha Mohanadoss prop->avg_samples = VADC_DEF_AVG_SAMPLES; 746e13d7572SSiddartha Mohanadoss } 747e13d7572SSiddartha Mohanadoss 7484f47a236SNuno Sá if (fwnode_property_read_bool(fwnode, "qcom,ratiometric")) 749e13d7572SSiddartha Mohanadoss prop->cal_method = ADC5_RATIOMETRIC_CAL; 750e13d7572SSiddartha Mohanadoss else 751e13d7572SSiddartha Mohanadoss prop->cal_method = ADC5_ABSOLUTE_CAL; 752e13d7572SSiddartha Mohanadoss 753e13d7572SSiddartha Mohanadoss /* 754e13d7572SSiddartha Mohanadoss * Default to using timer calibration. Using a fresh calibration value 755e13d7572SSiddartha Mohanadoss * for every conversion will increase the overall time for a request. 756e13d7572SSiddartha Mohanadoss */ 757e13d7572SSiddartha Mohanadoss prop->cal_val = ADC5_TIMER_CAL; 758e13d7572SSiddartha Mohanadoss 759e13d7572SSiddartha Mohanadoss dev_dbg(dev, "%02x name %s\n", chan, name); 760e13d7572SSiddartha Mohanadoss 761e13d7572SSiddartha Mohanadoss return 0; 762e13d7572SSiddartha Mohanadoss } 763e13d7572SSiddartha Mohanadoss 764e13d7572SSiddartha Mohanadoss static const struct adc5_data adc5_data_pmic = { 765e13d7572SSiddartha Mohanadoss .full_scale_code_volt = 0x70e4, 766e13d7572SSiddartha Mohanadoss .full_scale_code_cur = 0x2710, 767e13d7572SSiddartha Mohanadoss .adc_chans = adc5_chans_pmic, 768572e76e3SJishnu Prakash .info = &adc5_info, 769e13d7572SSiddartha Mohanadoss .decimation = (unsigned int [ADC5_DECIMATION_SAMPLES_MAX]) 770e13d7572SSiddartha Mohanadoss {250, 420, 840}, 771e13d7572SSiddartha Mohanadoss .hw_settle_1 = (unsigned int [VADC_HW_SETTLE_SAMPLES_MAX]) 772e13d7572SSiddartha Mohanadoss {15, 100, 200, 300, 400, 500, 600, 700, 773e13d7572SSiddartha Mohanadoss 800, 900, 1, 2, 4, 6, 8, 10}, 774e13d7572SSiddartha Mohanadoss .hw_settle_2 = (unsigned int [VADC_HW_SETTLE_SAMPLES_MAX]) 775e13d7572SSiddartha Mohanadoss {15, 100, 200, 300, 400, 500, 600, 700, 776e13d7572SSiddartha Mohanadoss 1, 2, 4, 8, 16, 32, 64, 128}, 777e13d7572SSiddartha Mohanadoss }; 778e13d7572SSiddartha Mohanadoss 779082111e5SJishnu Prakash static const struct adc5_data adc7_data_pmic = { 780082111e5SJishnu Prakash .full_scale_code_volt = 0x70e4, 781082111e5SJishnu Prakash .adc_chans = adc7_chans_pmic, 782082111e5SJishnu Prakash .info = &adc7_info, 783082111e5SJishnu Prakash .decimation = (unsigned int [ADC5_DECIMATION_SAMPLES_MAX]) 784082111e5SJishnu Prakash {85, 340, 1360}, 785082111e5SJishnu Prakash .hw_settle_2 = (unsigned int [VADC_HW_SETTLE_SAMPLES_MAX]) 786082111e5SJishnu Prakash {15, 100, 200, 300, 400, 500, 600, 700, 787082111e5SJishnu Prakash 1000, 2000, 4000, 8000, 16000, 32000, 788082111e5SJishnu Prakash 64000, 128000}, 789082111e5SJishnu Prakash }; 790082111e5SJishnu Prakash 791e13d7572SSiddartha Mohanadoss static const struct adc5_data adc5_data_pmic_rev2 = { 792e13d7572SSiddartha Mohanadoss .full_scale_code_volt = 0x4000, 793e13d7572SSiddartha Mohanadoss .full_scale_code_cur = 0x1800, 794e13d7572SSiddartha Mohanadoss .adc_chans = adc5_chans_rev2, 795572e76e3SJishnu Prakash .info = &adc5_info, 796e13d7572SSiddartha Mohanadoss .decimation = (unsigned int [ADC5_DECIMATION_SAMPLES_MAX]) 797e13d7572SSiddartha Mohanadoss {256, 512, 1024}, 798e13d7572SSiddartha Mohanadoss .hw_settle_1 = (unsigned int [VADC_HW_SETTLE_SAMPLES_MAX]) 799e13d7572SSiddartha Mohanadoss {0, 100, 200, 300, 400, 500, 600, 700, 800e13d7572SSiddartha Mohanadoss 800, 900, 1, 2, 4, 6, 8, 10}, 801e13d7572SSiddartha Mohanadoss .hw_settle_2 = (unsigned int [VADC_HW_SETTLE_SAMPLES_MAX]) 802e13d7572SSiddartha Mohanadoss {15, 100, 200, 300, 400, 500, 600, 700, 803e13d7572SSiddartha Mohanadoss 1, 2, 4, 8, 16, 32, 64, 128}, 804e13d7572SSiddartha Mohanadoss }; 805e13d7572SSiddartha Mohanadoss 806e13d7572SSiddartha Mohanadoss static const struct of_device_id adc5_match_table[] = { 807e13d7572SSiddartha Mohanadoss { 808e13d7572SSiddartha Mohanadoss .compatible = "qcom,spmi-adc5", 809e13d7572SSiddartha Mohanadoss .data = &adc5_data_pmic, 810e13d7572SSiddartha Mohanadoss }, 811e13d7572SSiddartha Mohanadoss { 812082111e5SJishnu Prakash .compatible = "qcom,spmi-adc7", 813082111e5SJishnu Prakash .data = &adc7_data_pmic, 814082111e5SJishnu Prakash }, 815082111e5SJishnu Prakash { 816e13d7572SSiddartha Mohanadoss .compatible = "qcom,spmi-adc-rev2", 817e13d7572SSiddartha Mohanadoss .data = &adc5_data_pmic_rev2, 818e13d7572SSiddartha Mohanadoss }, 819e13d7572SSiddartha Mohanadoss { } 820e13d7572SSiddartha Mohanadoss }; 821447ccb4eSBjorn Andersson MODULE_DEVICE_TABLE(of, adc5_match_table); 822e13d7572SSiddartha Mohanadoss 8234f47a236SNuno Sá static int adc5_get_fw_data(struct adc5_chip *adc) 824e13d7572SSiddartha Mohanadoss { 825e13d7572SSiddartha Mohanadoss const struct adc5_channels *adc_chan; 826e13d7572SSiddartha Mohanadoss struct iio_chan_spec *iio_chan; 827e13d7572SSiddartha Mohanadoss struct adc5_channel_prop prop, *chan_props; 828e13d7572SSiddartha Mohanadoss unsigned int index = 0; 829e13d7572SSiddartha Mohanadoss int ret; 830e13d7572SSiddartha Mohanadoss 8314f47a236SNuno Sá adc->nchannels = device_get_child_node_count(adc->dev); 832e13d7572SSiddartha Mohanadoss if (!adc->nchannels) 833e13d7572SSiddartha Mohanadoss return -EINVAL; 834e13d7572SSiddartha Mohanadoss 835e13d7572SSiddartha Mohanadoss adc->iio_chans = devm_kcalloc(adc->dev, adc->nchannels, 836e13d7572SSiddartha Mohanadoss sizeof(*adc->iio_chans), GFP_KERNEL); 837e13d7572SSiddartha Mohanadoss if (!adc->iio_chans) 838e13d7572SSiddartha Mohanadoss return -ENOMEM; 839e13d7572SSiddartha Mohanadoss 840e13d7572SSiddartha Mohanadoss adc->chan_props = devm_kcalloc(adc->dev, adc->nchannels, 841e13d7572SSiddartha Mohanadoss sizeof(*adc->chan_props), GFP_KERNEL); 842e13d7572SSiddartha Mohanadoss if (!adc->chan_props) 843e13d7572SSiddartha Mohanadoss return -ENOMEM; 844e13d7572SSiddartha Mohanadoss 845e13d7572SSiddartha Mohanadoss chan_props = adc->chan_props; 846e13d7572SSiddartha Mohanadoss iio_chan = adc->iio_chans; 8474f47a236SNuno Sá adc->data = device_get_match_data(adc->dev); 8489695a2a5SDmitry Baryshkov if (!adc->data) 8499695a2a5SDmitry Baryshkov adc->data = &adc5_data_pmic; 850e13d7572SSiddartha Mohanadoss 851*77dc3b17SJonathan Cameron device_for_each_child_node_scoped(adc->dev, child) { 8524f47a236SNuno Sá ret = adc5_get_fw_channel_data(adc, &prop, child, adc->data); 853*77dc3b17SJonathan Cameron if (ret) 854e13d7572SSiddartha Mohanadoss return ret; 855e13d7572SSiddartha Mohanadoss 856e13d7572SSiddartha Mohanadoss prop.scale_fn_type = 8579695a2a5SDmitry Baryshkov adc->data->adc_chans[prop.channel].scale_fn_type; 858e13d7572SSiddartha Mohanadoss *chan_props = prop; 8599695a2a5SDmitry Baryshkov adc_chan = &adc->data->adc_chans[prop.channel]; 860e13d7572SSiddartha Mohanadoss 861e13d7572SSiddartha Mohanadoss iio_chan->channel = prop.channel; 862e93cde03SMarijn Suijten iio_chan->datasheet_name = adc_chan->datasheet_name; 863e93cde03SMarijn Suijten iio_chan->extend_name = prop.channel_name; 864e13d7572SSiddartha Mohanadoss iio_chan->info_mask_separate = adc_chan->info_mask; 865e13d7572SSiddartha Mohanadoss iio_chan->type = adc_chan->type; 866e13d7572SSiddartha Mohanadoss iio_chan->address = index; 867e13d7572SSiddartha Mohanadoss iio_chan++; 868e13d7572SSiddartha Mohanadoss chan_props++; 869e13d7572SSiddartha Mohanadoss index++; 870e13d7572SSiddartha Mohanadoss } 871e13d7572SSiddartha Mohanadoss 872e13d7572SSiddartha Mohanadoss return 0; 873e13d7572SSiddartha Mohanadoss } 874e13d7572SSiddartha Mohanadoss 875e13d7572SSiddartha Mohanadoss static int adc5_probe(struct platform_device *pdev) 876e13d7572SSiddartha Mohanadoss { 877e13d7572SSiddartha Mohanadoss struct device *dev = &pdev->dev; 878e13d7572SSiddartha Mohanadoss struct iio_dev *indio_dev; 879e13d7572SSiddartha Mohanadoss struct adc5_chip *adc; 880e13d7572SSiddartha Mohanadoss struct regmap *regmap; 881e13d7572SSiddartha Mohanadoss int ret, irq_eoc; 882e13d7572SSiddartha Mohanadoss u32 reg; 883e13d7572SSiddartha Mohanadoss 884e13d7572SSiddartha Mohanadoss regmap = dev_get_regmap(dev->parent, NULL); 885e13d7572SSiddartha Mohanadoss if (!regmap) 886e13d7572SSiddartha Mohanadoss return -ENODEV; 887e13d7572SSiddartha Mohanadoss 8884f47a236SNuno Sá ret = device_property_read_u32(dev, "reg", ®); 889e13d7572SSiddartha Mohanadoss if (ret < 0) 890e13d7572SSiddartha Mohanadoss return ret; 891e13d7572SSiddartha Mohanadoss 892e13d7572SSiddartha Mohanadoss indio_dev = devm_iio_device_alloc(dev, sizeof(*adc)); 893e13d7572SSiddartha Mohanadoss if (!indio_dev) 894e13d7572SSiddartha Mohanadoss return -ENOMEM; 895e13d7572SSiddartha Mohanadoss 896e13d7572SSiddartha Mohanadoss adc = iio_priv(indio_dev); 897e13d7572SSiddartha Mohanadoss adc->regmap = regmap; 898e13d7572SSiddartha Mohanadoss adc->dev = dev; 899e13d7572SSiddartha Mohanadoss adc->base = reg; 900082111e5SJishnu Prakash 901e13d7572SSiddartha Mohanadoss init_completion(&adc->complete); 902e13d7572SSiddartha Mohanadoss mutex_init(&adc->lock); 903e13d7572SSiddartha Mohanadoss 9044f47a236SNuno Sá ret = adc5_get_fw_data(adc); 90504104842SMarijn Suijten if (ret) 90604104842SMarijn Suijten return dev_err_probe(dev, ret, "adc get dt data failed\n"); 907e13d7572SSiddartha Mohanadoss 908e13d7572SSiddartha Mohanadoss irq_eoc = platform_get_irq(pdev, 0); 909e13d7572SSiddartha Mohanadoss if (irq_eoc < 0) { 910e13d7572SSiddartha Mohanadoss if (irq_eoc == -EPROBE_DEFER || irq_eoc == -EINVAL) 911e13d7572SSiddartha Mohanadoss return irq_eoc; 912e13d7572SSiddartha Mohanadoss adc->poll_eoc = true; 913e13d7572SSiddartha Mohanadoss } else { 914e13d7572SSiddartha Mohanadoss ret = devm_request_irq(dev, irq_eoc, adc5_isr, 0, 915e13d7572SSiddartha Mohanadoss "pm-adc5", adc); 916e13d7572SSiddartha Mohanadoss if (ret) 917e13d7572SSiddartha Mohanadoss return ret; 918e13d7572SSiddartha Mohanadoss } 919e13d7572SSiddartha Mohanadoss 920e13d7572SSiddartha Mohanadoss indio_dev->name = pdev->name; 921e13d7572SSiddartha Mohanadoss indio_dev->modes = INDIO_DIRECT_MODE; 922572e76e3SJishnu Prakash indio_dev->info = adc->data->info; 923e13d7572SSiddartha Mohanadoss indio_dev->channels = adc->iio_chans; 924e13d7572SSiddartha Mohanadoss indio_dev->num_channels = adc->nchannels; 925e13d7572SSiddartha Mohanadoss 926e13d7572SSiddartha Mohanadoss return devm_iio_device_register(dev, indio_dev); 927e13d7572SSiddartha Mohanadoss } 928e13d7572SSiddartha Mohanadoss 929e13d7572SSiddartha Mohanadoss static struct platform_driver adc5_driver = { 930e13d7572SSiddartha Mohanadoss .driver = { 931fdb29f4dSDmitry Baryshkov .name = "qcom-spmi-adc5", 932e13d7572SSiddartha Mohanadoss .of_match_table = adc5_match_table, 933e13d7572SSiddartha Mohanadoss }, 934e13d7572SSiddartha Mohanadoss .probe = adc5_probe, 935e13d7572SSiddartha Mohanadoss }; 936e13d7572SSiddartha Mohanadoss module_platform_driver(adc5_driver); 937e13d7572SSiddartha Mohanadoss 938e13d7572SSiddartha Mohanadoss MODULE_ALIAS("platform:qcom-spmi-adc5"); 939e13d7572SSiddartha Mohanadoss MODULE_DESCRIPTION("Qualcomm Technologies Inc. PMIC5 ADC driver"); 940e13d7572SSiddartha Mohanadoss MODULE_LICENSE("GPL v2"); 941