| Author | Tokens | Token Proportion | Commits | Commit Proportion |
|---|---|---|---|---|
| Jonathan Santos | 4369 | 58.28% | 15 | 38.46% |
| Stefan Popa | 2100 | 28.01% | 2 | 5.13% |
| Sergiu Cuciurean | 788 | 10.51% | 4 | 10.26% |
| Cristian Pop | 146 | 1.95% | 1 | 2.56% |
| Jonathan Cameron | 52 | 0.69% | 8 | 20.51% |
| Ethan Tidmore | 33 | 0.44% | 1 | 2.56% |
| Lars-Peter Clausen | 2 | 0.03% | 2 | 5.13% |
| Javier Carrasco | 2 | 0.03% | 1 | 2.56% |
| Bartosz Golaszewski | 1 | 0.01% | 1 | 2.56% |
| Sebastian Andrzej Siewior | 1 | 0.01% | 1 | 2.56% |
| David Lechner | 1 | 0.01% | 1 | 2.56% |
| Uwe Kleine-König | 1 | 0.01% | 1 | 2.56% |
| Nuno Sá | 1 | 0.01% | 1 | 2.56% |
| Total | 7497 | 39 |
// SPDX-License-Identifier: GPL-2.0 /* * Analog Devices AD7768-1 SPI ADC driver * * Copyright 2017 Analog Devices Inc. */ #include <linux/array_size.h> #include <linux/bitfield.h> #include <linux/cleanup.h> #include <linux/clk.h> #include <linux/completion.h> #include <linux/delay.h> #include <linux/device.h> #include <linux/err.h> #include <linux/gpio/driver.h> #include <linux/gpio/consumer.h> #include <linux/interrupt.h> #include <linux/limits.h> #include <linux/math.h> #include <linux/minmax.h> #include <linux/module.h> #include <linux/mutex.h> #include <linux/rational.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/regulator/driver.h> #include <linux/sysfs.h> #include <linux/spi/spi.h> #include <linux/unaligned.h> #include <linux/units.h> #include <linux/util_macros.h> #include <linux/iio/buffer.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> #include <linux/iio/trigger.h> #include <linux/iio/triggered_buffer.h> #include <linux/iio/trigger_consumer.h> #include <dt-bindings/iio/adc/adi,ad7768-1.h> /* AD7768 registers definition */ #define AD7768_REG_CHIP_TYPE 0x3 #define AD7768_REG_PROD_ID_L 0x4 #define AD7768_REG_PROD_ID_H 0x5 #define AD7768_REG_CHIP_GRADE 0x6 #define AD7768_REG_SCRATCH_PAD 0x0A #define AD7768_REG_VENDOR_L 0x0C #define AD7768_REG_VENDOR_H 0x0D #define AD7768_REG_INTERFACE_FORMAT 0x14 #define AD7768_REG_POWER_CLOCK 0x15 #define AD7768_REG_ANALOG 0x16 #define AD7768_REG_ANALOG2 0x17 #define AD7768_REG_CONVERSION 0x18 #define AD7768_REG_DIGITAL_FILTER 0x19 #define AD7768_REG_SINC3_DEC_RATE_MSB 0x1A #define AD7768_REG_SINC3_DEC_RATE_LSB 0x1B #define AD7768_REG_DUTY_CYCLE_RATIO 0x1C #define AD7768_REG_SYNC_RESET 0x1D #define AD7768_REG_GPIO_CONTROL 0x1E #define AD7768_REG_GPIO_WRITE 0x1F #define AD7768_REG_GPIO_READ 0x20 #define AD7768_REG_OFFSET_HI 0x21 #define AD7768_REG_OFFSET_MID 0x22 #define AD7768_REG_OFFSET_LO 0x23 #define AD7768_REG_GAIN_HI 0x24 #define AD7768_REG_GAIN_MID 0x25 #define AD7768_REG_GAIN_LO 0x26 #define AD7768_REG_SPI_DIAG_ENABLE 0x28 #define AD7768_REG_ADC_DIAG_ENABLE 0x29 #define AD7768_REG_DIG_DIAG_ENABLE 0x2A #define AD7768_REG24_ADC_DATA 0x2C #define AD7768_REG_MASTER_STATUS 0x2D #define AD7768_REG_SPI_DIAG_STATUS 0x2E #define AD7768_REG_ADC_DIAG_STATUS 0x2F #define AD7768_REG_DIG_DIAG_STATUS 0x30 #define AD7768_REG_MCLK_COUNTER 0x31 #define AD7768_REG_COEFF_CONTROL 0x32 #define AD7768_REG24_COEFF_DATA 0x33 #define AD7768_REG_ACCESS_KEY 0x34 /* AD7768_REG_POWER_CLOCK */ #define AD7768_PWR_MCLK_DIV_MSK GENMASK(5, 4) #define AD7768_PWR_MCLK_DIV(x) FIELD_PREP(AD7768_PWR_MCLK_DIV_MSK, x) #define AD7768_PWR_PWRMODE_MSK GENMASK(1, 0) #define AD7768_PWR_PWRMODE(x) FIELD_PREP(AD7768_PWR_PWRMODE_MSK, x) /* AD7768_REG_DIGITAL_FILTER */ #define AD7768_DIG_FIL_EN_60HZ_REJ BIT(7) #define AD7768_DIG_FIL_FIL_MSK GENMASK(6, 4) #define AD7768_DIG_FIL_FIL(x) FIELD_PREP(AD7768_DIG_FIL_FIL_MSK, x) #define AD7768_DIG_FIL_DEC_MSK GENMASK(2, 0) #define AD7768_DIG_FIL_DEC_RATE(x) FIELD_PREP(AD7768_DIG_FIL_DEC_MSK, x) /* AD7768_REG_CONVERSION */ #define AD7768_CONV_MODE_MSK GENMASK(2, 0) #define AD7768_CONV_MODE(x) FIELD_PREP(AD7768_CONV_MODE_MSK, x) /* AD7768_REG_ANALOG2 */ #define AD7768_REG_ANALOG2_VCM_MSK GENMASK(2, 0) #define AD7768_REG_ANALOG2_VCM(x) FIELD_PREP(AD7768_REG_ANALOG2_VCM_MSK, (x)) /* AD7768_REG_GPIO_CONTROL */ #define AD7768_GPIO_UNIVERSAL_EN BIT(7) #define AD7768_GPIO_CONTROL_MSK GENMASK(3, 0) /* AD7768_REG_GPIO_WRITE */ #define AD7768_GPIO_WRITE_MSK GENMASK(3, 0) /* AD7768_REG_GPIO_READ */ #define AD7768_GPIO_READ_MSK GENMASK(3, 0) #define AD7768_VCM_OFF 0x07 #define ADAQ776X_GAIN_MAX_NANO (128 * NANO) #define ADAQ776X_MAX_GAIN_MODES 8 #define AD7768_TRIGGER_SOURCE_SYNC_IDX 0 #define AD7768_MAX_CHANNELS 1 #define ADAQ7768_PGA_PINS 3 enum ad7768_conv_mode { AD7768_CONTINUOUS, AD7768_ONE_SHOT, AD7768_SINGLE, AD7768_PERIODIC, AD7768_STANDBY }; enum ad7768_pwrmode { AD7768_ECO_MODE = 0, AD7768_MED_MODE = 2, AD7768_FAST_MODE = 3 }; enum ad7768_mclk_div { AD7768_MCLK_DIV_16, AD7768_MCLK_DIV_8, AD7768_MCLK_DIV_4, AD7768_MCLK_DIV_2 }; enum ad7768_filter_type { AD7768_FILTER_SINC5, AD7768_FILTER_SINC3, AD7768_FILTER_WIDEBAND, AD7768_FILTER_SINC3_REJ60, }; enum ad7768_filter_regval { AD7768_FILTER_REGVAL_SINC5 = 0, AD7768_FILTER_REGVAL_SINC5_X8 = 1, AD7768_FILTER_REGVAL_SINC5_X16 = 2, AD7768_FILTER_REGVAL_SINC3 = 3, AD7768_FILTER_REGVAL_WIDEBAND = 4, AD7768_FILTER_REGVAL_SINC3_REJ60 = 11, }; enum ad7768_scan_type { AD7768_SCAN_TYPE_NORMAL, AD7768_SCAN_TYPE_HIGH_SPEED, }; enum { AD7768_PGA_GAIN_0, AD7768_PGA_GAIN_1, AD7768_PGA_GAIN_2, AD7768_PGA_GAIN_3, AD7768_PGA_GAIN_4, AD7768_PGA_GAIN_5, AD7768_PGA_GAIN_6, AD7768_PGA_GAIN_7, }; enum { AD7768_AAF_IN1, AD7768_AAF_IN2, AD7768_AAF_IN3, }; /* PGA and AAF gains in V/V */ static const int adaq7768_gains[] = { [AD7768_PGA_GAIN_0] = 325, /* 0.325 */ [AD7768_PGA_GAIN_1] = 650, /* 0.650 */ [AD7768_PGA_GAIN_2] = 1300, /* 1.300 */ [AD7768_PGA_GAIN_3] = 2600, /* 2.600 */ [AD7768_PGA_GAIN_4] = 5200, /* 5.200 */ [AD7768_PGA_GAIN_5] = 10400, /* 10.400 */ [AD7768_PGA_GAIN_6] = 20800, /* 20.800 */ }; static const int adaq7769_gains[] = { [AD7768_PGA_GAIN_0] = 1000, /* 1.000 */ [AD7768_PGA_GAIN_1] = 2000, /* 2.000 */ [AD7768_PGA_GAIN_2] = 4000, /* 4.000 */ [AD7768_PGA_GAIN_3] = 8000, /* 8.000 */ [AD7768_PGA_GAIN_4] = 16000, /* 16.000 */ [AD7768_PGA_GAIN_5] = 32000, /* 32.000 */ [AD7768_PGA_GAIN_6] = 64000, /* 64.000 */ [AD7768_PGA_GAIN_7] = 128000, /* 128.000 */ }; static const int ad7768_aaf_gains_bp[] = { [AD7768_AAF_IN1] = 10000, /* 1.000 */ [AD7768_AAF_IN2] = 3640, /* 0.364 */ [AD7768_AAF_IN3] = 1430, /* 0.143 */ }; /* -3dB cutoff frequency multipliers (relative to ODR) for each filter type. */ static const int ad7768_filter_3db_odr_multiplier[] = { [AD7768_FILTER_SINC5] = 204, /* 0.204 */ [AD7768_FILTER_SINC3] = 262, /* 0.2617 */ [AD7768_FILTER_SINC3_REJ60] = 262, /* 0.2617 */ [AD7768_FILTER_WIDEBAND] = 433, /* 0.433 */ }; static const int ad7768_mclk_div_rates[] = { 16, 8, 4, 2, }; static const int ad7768_dec_rate_values[8] = { 8, 16, 32, 64, 128, 256, 512, 1024, }; /* Decimation rate range for sinc3 filter */ static const int ad7768_sinc3_dec_rate_range[3] = { 32, 32, 163840, }; /* * The AD7768-1 supports three primary filter types: * Sinc5, Sinc3, and Wideband. * However, the filter register values can also encode additional parameters * such as decimation rates and 60Hz rejection. This utility array separates * the filter type from these parameters. */ static const int ad7768_filter_regval_to_type[] = { [AD7768_FILTER_REGVAL_SINC5] = AD7768_FILTER_SINC5, [AD7768_FILTER_REGVAL_SINC5_X8] = AD7768_FILTER_SINC5, [AD7768_FILTER_REGVAL_SINC5_X16] = AD7768_FILTER_SINC5, [AD7768_FILTER_REGVAL_SINC3] = AD7768_FILTER_SINC3, [AD7768_FILTER_REGVAL_WIDEBAND] = AD7768_FILTER_WIDEBAND, [AD7768_FILTER_REGVAL_SINC3_REJ60] = AD7768_FILTER_SINC3_REJ60, }; static const char * const ad7768_filter_enum[] = { [AD7768_FILTER_SINC5] = "sinc5", [AD7768_FILTER_SINC3] = "sinc3", [AD7768_FILTER_WIDEBAND] = "wideband", [AD7768_FILTER_SINC3_REJ60] = "sinc3+rej60", }; static const struct iio_scan_type ad7768_scan_type[] = { [AD7768_SCAN_TYPE_NORMAL] = { .sign = 's', .realbits = 24, .storagebits = 32, .shift = 8, .endianness = IIO_BE, }, [AD7768_SCAN_TYPE_HIGH_SPEED] = { .sign = 's', .realbits = 16, .storagebits = 16, .endianness = IIO_BE, }, }; struct ad7768_chip_info { const char *name; const struct iio_chan_spec *channel_spec; int num_channels; const int *pga_gains; int num_pga_modes; int default_pga_mode; int pgia_mode2pin_offset; bool has_pga; bool has_variable_aaf; bool has_vcm_regulator; }; struct ad7768_state { struct spi_device *spi; struct regmap *regmap; struct regmap *regmap24; int vref_uv; struct regulator_dev *vcm_rdev; unsigned int vcm_output_sel; struct clk *mclk; unsigned int mclk_freq; unsigned int mclk_div; unsigned int oversampling_ratio; enum ad7768_filter_type filter_type; unsigned int samp_freq; unsigned int samp_freq_avail[ARRAY_SIZE(ad7768_mclk_div_rates)]; unsigned int samp_freq_avail_len; unsigned int pga_gain_mode; unsigned int aaf_gain; int scale_tbl[ADAQ776X_MAX_GAIN_MODES][2]; struct completion completion; struct iio_trigger *trig; struct gpio_descs *pga_gpios; struct gpio_desc *gpio_sync_in; struct gpio_desc *gpio_reset; const char *labels[AD7768_MAX_CHANNELS]; struct gpio_chip gpiochip; const struct ad7768_chip_info *chip; bool en_spi_sync; struct mutex pga_lock; /* protect device internal state (PGA) */ /* * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. */ union { struct { __be32 chan; aligned_s64 timestamp; } scan; __be32 d32; u8 d8[2]; } data __aligned(IIO_DMA_MINALIGN); }; static const struct regmap_range ad7768_regmap_rd_ranges[] = { regmap_reg_range(AD7768_REG_CHIP_TYPE, AD7768_REG_CHIP_GRADE), regmap_reg_range(AD7768_REG_SCRATCH_PAD, AD7768_REG_SCRATCH_PAD), regmap_reg_range(AD7768_REG_VENDOR_L, AD7768_REG_VENDOR_H), regmap_reg_range(AD7768_REG_INTERFACE_FORMAT, AD7768_REG_GAIN_LO), regmap_reg_range(AD7768_REG_SPI_DIAG_ENABLE, AD7768_REG_DIG_DIAG_ENABLE), regmap_reg_range(AD7768_REG_MASTER_STATUS, AD7768_REG_COEFF_CONTROL), regmap_reg_range(AD7768_REG_ACCESS_KEY, AD7768_REG_ACCESS_KEY), }; static const struct regmap_access_table ad7768_regmap_rd_table = { .yes_ranges = ad7768_regmap_rd_ranges, .n_yes_ranges = ARRAY_SIZE(ad7768_regmap_rd_ranges), }; static const struct regmap_range ad7768_regmap_wr_ranges[] = { regmap_reg_range(AD7768_REG_SCRATCH_PAD, AD7768_REG_SCRATCH_PAD), regmap_reg_range(AD7768_REG_INTERFACE_FORMAT, AD7768_REG_GPIO_WRITE), regmap_reg_range(AD7768_REG_OFFSET_HI, AD7768_REG_GAIN_LO), regmap_reg_range(AD7768_REG_SPI_DIAG_ENABLE, AD7768_REG_DIG_DIAG_ENABLE), regmap_reg_range(AD7768_REG_SPI_DIAG_STATUS, AD7768_REG_SPI_DIAG_STATUS), regmap_reg_range(AD7768_REG_COEFF_CONTROL, AD7768_REG_COEFF_CONTROL), regmap_reg_range(AD7768_REG_ACCESS_KEY, AD7768_REG_ACCESS_KEY), }; static const struct regmap_access_table ad7768_regmap_wr_table = { .yes_ranges = ad7768_regmap_wr_ranges, .n_yes_ranges = ARRAY_SIZE(ad7768_regmap_wr_ranges), }; static const struct regmap_config ad7768_regmap_config = { .name = "ad7768-1-8", .reg_bits = 8, .val_bits = 8, .read_flag_mask = BIT(6), .rd_table = &ad7768_regmap_rd_table, .wr_table = &ad7768_regmap_wr_table, .max_register = AD7768_REG_ACCESS_KEY, .use_single_write = true, .use_single_read = true, }; static const struct regmap_range ad7768_regmap24_rd_ranges[] = { regmap_reg_range(AD7768_REG24_ADC_DATA, AD7768_REG24_ADC_DATA), regmap_reg_range(AD7768_REG24_COEFF_DATA, AD7768_REG24_COEFF_DATA), }; static const struct regmap_access_table ad7768_regmap24_rd_table = { .yes_ranges = ad7768_regmap24_rd_ranges, .n_yes_ranges = ARRAY_SIZE(ad7768_regmap24_rd_ranges), }; static const struct regmap_range ad7768_regmap24_wr_ranges[] = { regmap_reg_range(AD7768_REG24_COEFF_DATA, AD7768_REG24_COEFF_DATA), }; static const struct regmap_access_table ad7768_regmap24_wr_table = { .yes_ranges = ad7768_regmap24_wr_ranges, .n_yes_ranges = ARRAY_SIZE(ad7768_regmap24_wr_ranges), }; static const struct regmap_config ad7768_regmap24_config = { .name = "ad7768-1-24", .reg_bits = 8, .val_bits = 24, .read_flag_mask = BIT(6), .rd_table = &ad7768_regmap24_rd_table, .wr_table = &ad7768_regmap24_wr_table, .max_register = AD7768_REG24_COEFF_DATA, }; static int ad7768_send_sync_pulse(struct ad7768_state *st) { if (st->en_spi_sync) return regmap_write(st->regmap, AD7768_REG_SYNC_RESET, 0x00); /* * The datasheet specifies a minimum SYNC_IN pulse width of 1.5 × Tmclk, * where Tmclk is the MCLK period. The supported MCLK frequencies range * from 0.6 MHz to 17 MHz, which corresponds to a minimum SYNC_IN pulse * width of approximately 2.5 µs in the worst-case scenario (0.6 MHz). * * Add a delay to ensure the pulse width is always sufficient to * trigger synchronization. */ gpiod_set_value_cansleep(st->gpio_sync_in, 1); fsleep(3); gpiod_set_value_cansleep(st->gpio_sync_in, 0); return 0; } static void ad7768_fill_samp_freq_tbl(struct ad7768_state *st) { unsigned int i, samp_freq_avail, freq_filtered; unsigned int len = 0; freq_filtered = DIV_ROUND_CLOSEST(st->mclk_freq, st->oversampling_ratio); for (i = 0; i < ARRAY_SIZE(ad7768_mclk_div_rates); i++) { samp_freq_avail = DIV_ROUND_CLOSEST(freq_filtered, ad7768_mclk_div_rates[i]); /* Sampling frequency cannot be lower than the minimum of 50 SPS */ if (samp_freq_avail < 50) continue; st->samp_freq_avail[len++] = samp_freq_avail; } st->samp_freq_avail_len = len; } static int ad7768_set_mclk_div(struct ad7768_state *st, unsigned int mclk_div) { unsigned int mclk_div_value; mclk_div_value = AD7768_PWR_MCLK_DIV(mclk_div); /* * Set power mode based on mclk_div value. * ECO_MODE is only recommended for MCLK_DIV = 16. */ mclk_div_value |= mclk_div > AD7768_MCLK_DIV_16 ? AD7768_PWR_PWRMODE(AD7768_FAST_MODE) : AD7768_PWR_PWRMODE(AD7768_ECO_MODE); return regmap_update_bits(st->regmap, AD7768_REG_POWER_CLOCK, AD7768_PWR_MCLK_DIV_MSK | AD7768_PWR_PWRMODE_MSK, mclk_div_value); } static int ad7768_set_mode(struct ad7768_state *st, enum ad7768_conv_mode mode) { return regmap_update_bits(st->regmap, AD7768_REG_CONVERSION, AD7768_CONV_MODE_MSK, AD7768_CONV_MODE(mode)); } static int ad7768_scan_direct(struct iio_dev *indio_dev) { struct ad7768_state *st = iio_priv(indio_dev); int readval, ret; reinit_completion(&st->completion); ret = ad7768_set_mode(st, AD7768_ONE_SHOT); if (ret < 0) return ret; ret = wait_for_completion_timeout(&st->completion, msecs_to_jiffies(1000)); if (!ret) return -ETIMEDOUT; ret = regmap_read(st->regmap24, AD7768_REG24_ADC_DATA, &readval); if (ret) return ret; /* * When the decimation rate is set to x8, the ADC data precision is * reduced from 24 bits to 16 bits. Since the AD7768_REG_ADC_DATA * register provides 24-bit data, the precision is reduced by * right-shifting the read value by 8 bits. */ if (st->oversampling_ratio == 8) readval >>= 8; /* * Any SPI configuration of the AD7768-1 can only be * performed in continuous conversion mode. */ ret = ad7768_set_mode(st, AD7768_CONTINUOUS); if (ret < 0) return ret; return readval; } static int ad7768_reg_access(struct iio_dev *indio_dev, unsigned int reg, unsigned int writeval, unsigned int *readval) { struct ad7768_state *st = iio_priv(indio_dev); int ret; if (!iio_device_claim_direct(indio_dev)) return -EBUSY; ret = -EINVAL; if (readval) { if (regmap_check_range_table(st->regmap, reg, &ad7768_regmap_rd_table)) ret = regmap_read(st->regmap, reg, readval); if (regmap_check_range_table(st->regmap24, reg, &ad7768_regmap24_rd_table)) ret = regmap_read(st->regmap24, reg, readval); } else { if (regmap_check_range_table(st->regmap, reg, &ad7768_regmap_wr_table)) ret = regmap_write(st->regmap, reg, writeval); if (regmap_check_range_table(st->regmap24, reg, &ad7768_regmap24_wr_table)) ret = regmap_write(st->regmap24, reg, writeval); } iio_device_release_direct(indio_dev); return ret; } static int ad7768_fill_scale_tbl(struct iio_dev *dev) { struct ad7768_state *st = iio_priv(dev); const struct iio_scan_type *scan_type; int val, val2, tmp0, tmp1, i; struct u32_fract fract; unsigned long n, d; u64 tmp2; scan_type = iio_get_current_scan_type(dev, &dev->channels[0]); if (IS_ERR(scan_type)) { dev_err(&st->spi->dev, "Failed to get scan type.\n"); return PTR_ERR(scan_type); } if (scan_type->sign == 's') val2 = scan_type->realbits - 1; else val2 = scan_type->realbits; for (i = 0; i < st->chip->num_pga_modes; i++) { /* Convert gain to a fraction format */ fract.numerator = st->chip->pga_gains[i]; fract.denominator = MILLI; if (st->chip->has_variable_aaf) { fract.numerator *= ad7768_aaf_gains_bp[st->aaf_gain]; fract.denominator *= PERMYRIAD; } rational_best_approximation(fract.numerator, fract.denominator, INT_MAX, INT_MAX, &n, &d); val = mult_frac(st->vref_uv, d, n); /* Would multiply by NANO here, but value is already in milli */ tmp2 = ((u64)val * MICRO) >> val2; tmp0 = div_u64_rem(tmp2, NANO, &tmp1); st->scale_tbl[i][0] = tmp0; /* Integer part */ st->scale_tbl[i][1] = abs(tmp1); /* Fractional part */ } return 0; } static int ad7768_set_sinc3_dec_rate(struct ad7768_state *st, unsigned int dec_rate) { unsigned int max_dec_rate; u8 dec_rate_reg[2]; u16 regval; int ret; /* * Maximum dec_rate is limited by the MCLK_DIV value and by the ODR. * The edge case is for MCLK_DIV = 2, ODR = 50 SPS. * max_dec_rate <= MCLK / (2 * 50) */ max_dec_rate = st->mclk_freq / 100; dec_rate = clamp(dec_rate, 32, max_dec_rate); /* * Calculate the equivalent value to sinc3 decimation ratio * to be written on the SINC3_DEC_RATE register: * Value = (DEC_RATE / 32) - 1 */ dec_rate = DIV_ROUND_UP(dec_rate, 32) - 1; /* * The SINC3_DEC_RATE value is a 13-bit value split across two * registers: MSB [12:8] and LSB [7:0]. Prepare the 13-bit value using * FIELD_PREP() and store it with the right endianness in dec_rate_reg. */ regval = FIELD_PREP(GENMASK(12, 0), dec_rate); put_unaligned_be16(regval, dec_rate_reg); ret = regmap_bulk_write(st->regmap, AD7768_REG_SINC3_DEC_RATE_MSB, dec_rate_reg, 2); if (ret) return ret; st->oversampling_ratio = (dec_rate + 1) * 32; return 0; } static int ad7768_configure_dig_fil(struct iio_dev *dev, enum ad7768_filter_type filter_type, unsigned int dec_rate) { struct ad7768_state *st = iio_priv(dev); unsigned int dec_rate_idx, dig_filter_regval; int ret; switch (filter_type) { case AD7768_FILTER_SINC3: dig_filter_regval = AD7768_DIG_FIL_FIL(AD7768_FILTER_REGVAL_SINC3); break; case AD7768_FILTER_SINC3_REJ60: dig_filter_regval = AD7768_DIG_FIL_FIL(AD7768_FILTER_REGVAL_SINC3) | AD7768_DIG_FIL_EN_60HZ_REJ; break; case AD7768_FILTER_WIDEBAND: /* Skip decimations 8 and 16, not supported by the wideband filter */ dec_rate_idx = find_closest(dec_rate, &ad7768_dec_rate_values[2], ARRAY_SIZE(ad7768_dec_rate_values) - 2); dig_filter_regval = AD7768_DIG_FIL_FIL(AD7768_FILTER_REGVAL_WIDEBAND) | AD7768_DIG_FIL_DEC_RATE(dec_rate_idx); /* Correct the index offset */ dec_rate_idx += 2; break; case AD7768_FILTER_SINC5: dec_rate_idx = find_closest(dec_rate, ad7768_dec_rate_values, ARRAY_SIZE(ad7768_dec_rate_values)); /* * Decimations 8 (idx 0) and 16 (idx 1) are set in the * FILTER[6:4] field. The other decimations are set in the * DEC_RATE[2:0] field, and the idx needs to be offsetted by two. */ if (dec_rate_idx == 0) dig_filter_regval = AD7768_DIG_FIL_FIL(AD7768_FILTER_REGVAL_SINC5_X8); else if (dec_rate_idx == 1) dig_filter_regval = AD7768_DIG_FIL_FIL(AD7768_FILTER_REGVAL_SINC5_X16); else dig_filter_regval = AD7768_DIG_FIL_FIL(AD7768_FILTER_REGVAL_SINC5) | AD7768_DIG_FIL_DEC_RATE(dec_rate_idx - 2); break; } ret = regmap_write(st->regmap, AD7768_REG_DIGITAL_FILTER, dig_filter_regval); if (ret) return ret; st->filter_type = filter_type; /* * The decimation for SINC3 filters are configured in different * registers. */ if (filter_type == AD7768_FILTER_SINC3 || filter_type == AD7768_FILTER_SINC3_REJ60) { ret = ad7768_set_sinc3_dec_rate(st, dec_rate); if (ret) return ret; } else { st->oversampling_ratio = ad7768_dec_rate_values[dec_rate_idx]; } /* Update scale table: scale values vary according to the precision */ ret = ad7768_fill_scale_tbl(dev); if (ret) return ret; ad7768_fill_samp_freq_tbl(st); /* A sync-in pulse is required after every configuration change */ return ad7768_send_sync_pulse(st); } static int ad7768_setup_pga(struct device *dev, struct ad7768_state *st) { st->pga_gpios = devm_gpiod_get_array(dev, "pga", GPIOD_OUT_LOW); if (IS_ERR(st->pga_gpios)) return dev_err_probe(dev, PTR_ERR(st->pga_gpios), "Failed to get PGA gpios.\n"); if (st->pga_gpios->ndescs != ADAQ7768_PGA_PINS) return dev_err_probe(dev, -EINVAL, "Expected %d GPIOs for PGA control.\n", ADAQ7768_PGA_PINS); return 0; } static int ad7768_calc_pga_gain(struct ad7768_state *st, int gain_int, int gain_fract, int precision) { u64 gain_nano; u32 tmp; gain_nano = gain_int * NANO + gain_fract; gain_nano = clamp(gain_nano, 0, ADAQ776X_GAIN_MAX_NANO); tmp = DIV_ROUND_CLOSEST_ULL(gain_nano << precision, NANO); gain_nano = DIV_ROUND_CLOSEST(st->vref_uv, tmp); if (st->chip->has_variable_aaf) gain_nano = DIV_ROUND_CLOSEST_ULL(gain_nano * PERMYRIAD, ad7768_aaf_gains_bp[st->aaf_gain]); return find_closest(gain_nano, st->chip->pga_gains, (int)st->chip->num_pga_modes); } static int ad7768_set_pga_gain(struct ad7768_state *st, int gain_mode) { int pgia_pins_value = abs(gain_mode - st->chip->pgia_mode2pin_offset); DECLARE_BITMAP(bitmap, ADAQ7768_PGA_PINS) = { }; int ret; guard(mutex)(&st->pga_lock); bitmap_write(bitmap, pgia_pins_value, 0, ADAQ7768_PGA_PINS); ret = gpiod_multi_set_value_cansleep(st->pga_gpios, bitmap); if (ret) return ret; st->pga_gain_mode = gain_mode; return 0; } static int ad7768_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) { struct iio_dev *indio_dev = gpiochip_get_data(chip); struct ad7768_state *st = iio_priv(indio_dev); int ret; if (!iio_device_claim_direct(indio_dev)) return -EBUSY; ret = regmap_clear_bits(st->regmap, AD7768_REG_GPIO_CONTROL, BIT(offset)); iio_device_release_direct(indio_dev); return ret; } static int ad7768_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, int value) { struct iio_dev *indio_dev = gpiochip_get_data(chip); struct ad7768_state *st = iio_priv(indio_dev); int ret; if (!iio_device_claim_direct(indio_dev)) return -EBUSY; ret = regmap_set_bits(st->regmap, AD7768_REG_GPIO_CONTROL, BIT(offset)); iio_device_release_direct(indio_dev); return ret; } static int ad7768_gpio_get(struct gpio_chip *chip, unsigned int offset) { struct iio_dev *indio_dev = gpiochip_get_data(chip); struct ad7768_state *st = iio_priv(indio_dev); unsigned int val; int ret; if (!iio_device_claim_direct(indio_dev)) return -EBUSY; ret = regmap_read(st->regmap, AD7768_REG_GPIO_CONTROL, &val); if (ret) goto err_release; /* * If the GPIO is configured as an output, read the current value from * AD7768_REG_GPIO_WRITE. Otherwise, read the input value from * AD7768_REG_GPIO_READ. */ if (val & BIT(offset)) ret = regmap_read(st->regmap, AD7768_REG_GPIO_WRITE, &val); else ret = regmap_read(st->regmap, AD7768_REG_GPIO_READ, &val); if (ret) goto err_release; ret = !!(val & BIT(offset)); err_release: iio_device_release_direct(indio_dev); return ret; } static int ad7768_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) { struct iio_dev *indio_dev = gpiochip_get_data(chip); struct ad7768_state *st = iio_priv(indio_dev); unsigned int val; int ret; if (!iio_device_claim_direct(indio_dev)) return -EBUSY; ret = regmap_read(st->regmap, AD7768_REG_GPIO_CONTROL, &val); if (ret) goto err_release; if (val & BIT(offset)) ret = regmap_assign_bits(st->regmap, AD7768_REG_GPIO_WRITE, BIT(offset), value); err_release: iio_device_release_direct(indio_dev); return ret; } static int ad7768_gpio_init(struct iio_dev *indio_dev) { struct ad7768_state *st = iio_priv(indio_dev); int ret; ret = regmap_write(st->regmap, AD7768_REG_GPIO_CONTROL, AD7768_GPIO_UNIVERSAL_EN); if (ret) return ret; st->gpiochip = (struct gpio_chip) { .label = "ad7768_1_gpios", .base = -1, .ngpio = 4, .parent = &st->spi->dev, .can_sleep = true, .direction_input = ad7768_gpio_direction_input, .direction_output = ad7768_gpio_direction_output, .get = ad7768_gpio_get, .set = ad7768_gpio_set, .owner = THIS_MODULE, }; return devm_gpiochip_add_data(&st->spi->dev, &st->gpiochip, indio_dev); } static int ad7768_set_freq(struct ad7768_state *st, unsigned int freq) { unsigned int idx, mclk_div; int ret; freq = clamp(freq, 50, 1024000); mclk_div = DIV_ROUND_CLOSEST(st->mclk_freq, freq * st->oversampling_ratio); /* Find the closest match for the desired sampling frequency */ idx = find_closest_descending(mclk_div, ad7768_mclk_div_rates, ARRAY_SIZE(ad7768_mclk_div_rates)); /* Set both the mclk_div and pwrmode */ ret = ad7768_set_mclk_div(st, idx); if (ret) return ret; st->samp_freq = DIV_ROUND_CLOSEST(st->mclk_freq, ad7768_mclk_div_rates[idx] * st->oversampling_ratio); /* A sync-in pulse is required after every configuration change */ return ad7768_send_sync_pulse(st); } static int ad7768_set_filter_type_attr(struct iio_dev *dev, const struct iio_chan_spec *chan, unsigned int filter) { struct ad7768_state *st = iio_priv(dev); int ret; ret = ad7768_configure_dig_fil(dev, filter, st->oversampling_ratio); if (ret) return ret; /* Update sampling frequency */ return ad7768_set_freq(st, st->samp_freq); } static int ad7768_get_filter_type_attr(struct iio_dev *dev, const struct iio_chan_spec *chan) { struct ad7768_state *st = iio_priv(dev); int ret; unsigned int mode, mask; ret = regmap_read(st->regmap, AD7768_REG_DIGITAL_FILTER, &mode); if (ret) return ret; mask = AD7768_DIG_FIL_EN_60HZ_REJ | AD7768_DIG_FIL_FIL_MSK; /* From the register value, get the corresponding filter type */ return ad7768_filter_regval_to_type[FIELD_GET(mask, mode)]; } static int ad7768_update_dec_rate(struct iio_dev *dev, unsigned int dec_rate) { struct ad7768_state *st = iio_priv(dev); int ret; ret = ad7768_configure_dig_fil(dev, st->filter_type, dec_rate); if (ret) return ret; /* Update sampling frequency */ return ad7768_set_freq(st, st->samp_freq); } static const struct iio_enum ad7768_filter_type_iio_enum = { .items = ad7768_filter_enum, .num_items = ARRAY_SIZE(ad7768_filter_enum), .set = ad7768_set_filter_type_attr, .get = ad7768_get_filter_type_attr, }; static const struct iio_chan_spec_ext_info ad7768_ext_info[] = { IIO_ENUM("filter_type", IIO_SHARED_BY_ALL, &ad7768_filter_type_iio_enum), IIO_ENUM_AVAILABLE("filter_type", IIO_SHARED_BY_ALL, &ad7768_filter_type_iio_enum), { } }; #define AD7768_CHAN(_idx, _msk_avail) \ { \ .type = IIO_VOLTAGE, \ .info_mask_separate_available = _msk_avail, \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | \ BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ .ext_info = ad7768_ext_info, \ .indexed = 1, \ .channel = _idx, \ .scan_index = _idx, \ .has_ext_scan_type = 1, \ .ext_scan_type = ad7768_scan_type, \ .num_ext_scan_type = ARRAY_SIZE(ad7768_scan_type), \ } static const struct iio_chan_spec ad7768_channels[] = { AD7768_CHAN(0, 0), }; static const struct iio_chan_spec adaq776x_channels[] = { AD7768_CHAN(0, BIT(IIO_CHAN_INFO_SCALE)), }; static int ad7768_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long info) { struct ad7768_state *st = iio_priv(indio_dev); const struct iio_scan_type *scan_type; int ret, temp; scan_type = iio_get_current_scan_type(indio_dev, chan); if (IS_ERR(scan_type)) return PTR_ERR(scan_type); switch (info) { case IIO_CHAN_INFO_RAW: if (!iio_device_claim_direct(indio_dev)) return -EBUSY; ret = ad7768_scan_direct(indio_dev); iio_device_release_direct(indio_dev); if (ret < 0) return ret; *val = sign_extend32(ret, scan_type->realbits - 1); return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: if (st->chip->has_pga) { guard(mutex)(&st->pga_lock); *val = st->scale_tbl[st->pga_gain_mode][0]; *val2 = st->scale_tbl[st->pga_gain_mode][1]; return IIO_VAL_INT_PLUS_NANO; } temp = (st->vref_uv * 2) / 1000; if (st->chip->has_variable_aaf) temp = (temp * PERMYRIAD) / ad7768_aaf_gains_bp[st->aaf_gain]; *val = temp; *val2 = scan_type->realbits; return IIO_VAL_FRACTIONAL_LOG2; case IIO_CHAN_INFO_SAMP_FREQ: *val = st->samp_freq; return IIO_VAL_INT; case IIO_CHAN_INFO_OVERSAMPLING_RATIO: *val = st->oversampling_ratio; return IIO_VAL_INT; case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: temp = st->samp_freq * ad7768_filter_3db_odr_multiplier[st->filter_type]; *val = DIV_ROUND_CLOSEST(temp, MILLI); return IIO_VAL_INT; } return -EINVAL; } static int ad7768_read_avail(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, const int **vals, int *type, int *length, long info) { struct ad7768_state *st = iio_priv(indio_dev); unsigned int shift; switch (info) { case IIO_CHAN_INFO_OVERSAMPLING_RATIO: /* * Sinc3 filter allows a wider range of OSR values, so show * the available values in range format. */ if (st->filter_type == AD7768_FILTER_SINC3 || st->filter_type == AD7768_FILTER_SINC3_REJ60) { *vals = (int *)ad7768_sinc3_dec_rate_range; *type = IIO_VAL_INT; return IIO_AVAIL_RANGE; } shift = st->filter_type == AD7768_FILTER_SINC5 ? 0 : 2; *vals = (int *)&ad7768_dec_rate_values[shift]; *length = ARRAY_SIZE(ad7768_dec_rate_values) - shift; *type = IIO_VAL_INT; return IIO_AVAIL_LIST; case IIO_CHAN_INFO_SAMP_FREQ: *vals = (int *)st->samp_freq_avail; *length = st->samp_freq_avail_len; *type = IIO_VAL_INT; return IIO_AVAIL_LIST; case IIO_CHAN_INFO_SCALE: *vals = (int *)st->scale_tbl; *length = st->chip->num_pga_modes * 2; *type = IIO_VAL_INT_PLUS_NANO; return IIO_AVAIL_LIST; default: return -EINVAL; } } static int ad7768_write_raw_get_fmt(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, long mask) { switch (mask) { case IIO_CHAN_INFO_SCALE: return IIO_VAL_INT_PLUS_NANO; default: return IIO_VAL_INT_PLUS_MICRO; } } static int ad7768_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long info) { struct ad7768_state *st = iio_priv(indio_dev); const struct iio_scan_type *scan_type; int ret; scan_type = iio_get_current_scan_type(indio_dev, chan); if (IS_ERR(scan_type)) return PTR_ERR(scan_type); switch (info) { case IIO_CHAN_INFO_SAMP_FREQ: if (!iio_device_claim_direct(indio_dev)) return -EBUSY; ret = ad7768_set_freq(st, val); iio_device_release_direct(indio_dev); return ret; case IIO_CHAN_INFO_OVERSAMPLING_RATIO: if (!iio_device_claim_direct(indio_dev)) return -EBUSY; ret = ad7768_update_dec_rate(indio_dev, val); iio_device_release_direct(indio_dev); return ret; case IIO_CHAN_INFO_SCALE: { int gain_mode; if (!st->chip->has_pga) return -EOPNOTSUPP; if (scan_type->sign == 's') gain_mode = ad7768_calc_pga_gain(st, val, val2, scan_type->realbits - 1); else gain_mode = ad7768_calc_pga_gain(st, val, val2, scan_type->realbits); return ad7768_set_pga_gain(st, gain_mode); } default: return -EINVAL; } } static int ad7768_read_label(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, char *label) { struct ad7768_state *st = iio_priv(indio_dev); return sysfs_emit(label, "%s\n", st->labels[chan->channel]); } static int ad7768_get_current_scan_type(const struct iio_dev *indio_dev, const struct iio_chan_spec *chan) { struct ad7768_state *st = iio_priv(indio_dev); return st->oversampling_ratio == 8 ? AD7768_SCAN_TYPE_HIGH_SPEED : AD7768_SCAN_TYPE_NORMAL; } static const struct iio_info ad7768_info = { .read_raw = &ad7768_read_raw, .read_avail = &ad7768_read_avail, .write_raw = &ad7768_write_raw, .write_raw_get_fmt = &ad7768_write_raw_get_fmt, .read_label = ad7768_read_label, .get_current_scan_type = &ad7768_get_current_scan_type, .debugfs_reg_access = &ad7768_reg_access, }; static struct fwnode_handle * ad7768_fwnode_find_reference_args(const struct fwnode_handle *fwnode, const char *name, const char *nargs_prop, unsigned int nargs, unsigned int index, struct fwnode_reference_args *args) { int ret; ret = fwnode_property_get_reference_args(fwnode, name, nargs_prop, nargs, index, args); return ret ? ERR_PTR(ret) : args->fwnode; } static int ad7768_trigger_sources_sync_setup(struct device *dev, struct fwnode_handle *fwnode, struct ad7768_state *st) { struct fwnode_reference_args args; struct fwnode_handle *ref __free(fwnode_handle) = ad7768_fwnode_find_reference_args(fwnode, "trigger-sources", "#trigger-source-cells", 0, AD7768_TRIGGER_SOURCE_SYNC_IDX, &args); if (IS_ERR(ref)) return PTR_ERR(ref); ref = args.fwnode; /* First, try getting the GPIO trigger source */ if (fwnode_device_is_compatible(ref, "gpio-trigger")) { st->gpio_sync_in = devm_fwnode_gpiod_get_index(dev, ref, NULL, 0, GPIOD_OUT_LOW, "sync-in"); return PTR_ERR_OR_ZERO(st->gpio_sync_in); } /* * TODO: Support the other cases when we have a trigger subsystem * to reliably handle other types of devices as trigger sources. * * For now, return an error message. For self triggering, omit the * trigger-sources property. */ return dev_err_probe(dev, -EOPNOTSUPP, "Invalid synchronization trigger source\n"); } static int ad7768_trigger_sources_get_sync(struct device *dev, struct ad7768_state *st) { struct fwnode_handle *fwnode = dev_fwnode(dev); /* * The AD7768-1 allows two primary methods for driving the SYNC_IN pin * to synchronize one or more devices: * 1. Using an external GPIO. * 2. Using a SPI command, where the SYNC_OUT pin generates a * synchronization pulse that drives the SYNC_IN pin. */ if (fwnode_property_present(fwnode, "trigger-sources")) return ad7768_trigger_sources_sync_setup(dev, fwnode, st); /* * In the absence of trigger-sources property, enable self * synchronization over SPI (SYNC_OUT). */ st->en_spi_sync = true; return 0; } static int ad7768_setup(struct iio_dev *indio_dev) { struct ad7768_state *st = iio_priv(indio_dev); int ret; st->gpio_reset = devm_gpiod_get_optional(&st->spi->dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(st->gpio_reset)) return PTR_ERR(st->gpio_reset); if (st->gpio_reset) { fsleep(10); gpiod_set_value_cansleep(st->gpio_reset, 0); fsleep(200); } else { /* * Two writes to the SPI_RESET[1:0] bits are required to initiate * a software reset. The bits must first be set to 11, and then * to 10. When the sequence is detected, the reset occurs. * See the datasheet, page 70. */ ret = regmap_write(st->regmap, AD7768_REG_SYNC_RESET, 0x3); if (ret) return ret; ret = regmap_write(st->regmap, AD7768_REG_SYNC_RESET, 0x2); if (ret) return ret; } /* For backwards compatibility, try the adi,sync-in-gpios property */ st->gpio_sync_in = devm_gpiod_get_optional(&st->spi->dev, "adi,sync-in", GPIOD_OUT_LOW); if (IS_ERR(st->gpio_sync_in)) return PTR_ERR(st->gpio_sync_in); /* * If the synchronization is not defined by adi,sync-in-gpios, try the * trigger-sources. */ if (!st->gpio_sync_in) { ret = ad7768_trigger_sources_get_sync(&st->spi->dev, st); if (ret) return ret; } /* Only create a Chip GPIO if flagged for it */ if (device_property_read_bool(&st->spi->dev, "gpio-controller")) { ret = ad7768_gpio_init(indio_dev); if (ret) return ret; } /* * Set Default Digital Filter configuration: * SINC5 filter with x32 Decimation rate */ ret = ad7768_configure_dig_fil(indio_dev, AD7768_FILTER_SINC5, 32); if (ret) return ret; /* Set the default sampling frequency to 32000 kSPS */ return ad7768_set_freq(st, 32000); } static irqreturn_t ad7768_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct ad7768_state *st = iio_priv(indio_dev); const struct iio_scan_type *scan_type; int ret; scan_type = iio_get_current_scan_type(indio_dev, &indio_dev->channels[0]); if (IS_ERR(scan_type)) goto out; ret = spi_read(st->spi, &st->data.scan.chan, BITS_TO_BYTES(scan_type->realbits)); if (ret < 0) goto out; iio_push_to_buffers_with_ts(indio_dev, &st->data.scan, sizeof(st->data.scan), iio_get_time_ns(indio_dev)); out: iio_trigger_notify_done(indio_dev->trig); return IRQ_HANDLED; } static irqreturn_t ad7768_interrupt(int irq, void *dev_id) { struct iio_dev *indio_dev = dev_id; struct ad7768_state *st = iio_priv(indio_dev); if (iio_buffer_enabled(indio_dev)) iio_trigger_poll(st->trig); else complete(&st->completion); return IRQ_HANDLED; }; static int ad7768_buffer_postenable(struct iio_dev *indio_dev) { struct ad7768_state *st = iio_priv(indio_dev); /* * Write a 1 to the LSB of the INTERFACE_FORMAT register to enter * continuous read mode. Subsequent data reads do not require an * initial 8-bit write to query the ADC_DATA register. */ return regmap_write(st->regmap, AD7768_REG_INTERFACE_FORMAT, 0x01); } static int ad7768_buffer_predisable(struct iio_dev *indio_dev) { struct ad7768_state *st = iio_priv(indio_dev); unsigned int unused; /* * To exit continuous read mode, perform a single read of the ADC_DATA * reg (0x2C), which allows further configuration of the device. */ return regmap_read(st->regmap24, AD7768_REG24_ADC_DATA, &unused); } static const struct iio_buffer_setup_ops ad7768_buffer_ops = { .postenable = &ad7768_buffer_postenable, .predisable = &ad7768_buffer_predisable, }; static const struct iio_trigger_ops ad7768_trigger_ops = { .validate_device = iio_trigger_validate_own_device, }; static int ad7768_set_channel_label(struct iio_dev *indio_dev, int num_channels) { struct ad7768_state *st = iio_priv(indio_dev); struct device *device = indio_dev->dev.parent; const char *label; int crt_ch = 0; device_for_each_child_node_scoped(device, child) { if (fwnode_property_read_u32(child, "reg", &crt_ch)) continue; if (crt_ch >= num_channels) continue; if (fwnode_property_read_string(child, "label", &label)) continue; st->labels[crt_ch] = label; } return 0; } static int ad7768_triggered_buffer_alloc(struct iio_dev *indio_dev) { struct ad7768_state *st = iio_priv(indio_dev); int ret; st->trig = devm_iio_trigger_alloc(indio_dev->dev.parent, "%s-dev%d", indio_dev->name, iio_device_id(indio_dev)); if (!st->trig) return -ENOMEM; st->trig->ops = &ad7768_trigger_ops; iio_trigger_set_drvdata(st->trig, indio_dev); ret = devm_iio_trigger_register(indio_dev->dev.parent, st->trig); if (ret) return ret; indio_dev->trig = iio_trigger_get(st->trig); return devm_iio_triggered_buffer_setup(indio_dev->dev.parent, indio_dev, &iio_pollfunc_store_time, &ad7768_trigger_handler, &ad7768_buffer_ops); } static int ad7768_vcm_enable(struct regulator_dev *rdev) { struct iio_dev *indio_dev = rdev_get_drvdata(rdev); struct ad7768_state *st = iio_priv(indio_dev); int ret, regval; if (!iio_device_claim_direct(indio_dev)) return -EBUSY; /* To enable, set the last selected output */ regval = AD7768_REG_ANALOG2_VCM(st->vcm_output_sel + 1); ret = regmap_update_bits(st->regmap, AD7768_REG_ANALOG2, AD7768_REG_ANALOG2_VCM_MSK, regval); iio_device_release_direct(indio_dev); return ret; } static int ad7768_vcm_disable(struct regulator_dev *rdev) { struct iio_dev *indio_dev = rdev_get_drvdata(rdev); struct ad7768_state *st = iio_priv(indio_dev); int ret; if (!iio_device_claim_direct(indio_dev)) return -EBUSY; ret = regmap_update_bits(st->regmap, AD7768_REG_ANALOG2, AD7768_REG_ANALOG2_VCM_MSK, AD7768_VCM_OFF); iio_device_release_direct(indio_dev); return ret; } static int ad7768_vcm_is_enabled(struct regulator_dev *rdev) { struct iio_dev *indio_dev = rdev_get_drvdata(rdev); struct ad7768_state *st = iio_priv(indio_dev); int ret, val; if (!iio_device_claim_direct(indio_dev)) return -EBUSY; ret = regmap_read(st->regmap, AD7768_REG_ANALOG2, &val); iio_device_release_direct(indio_dev); if (ret) return ret; return FIELD_GET(AD7768_REG_ANALOG2_VCM_MSK, val) != AD7768_VCM_OFF; } static int ad7768_set_voltage_sel(struct regulator_dev *rdev, unsigned int selector) { unsigned int regval = AD7768_REG_ANALOG2_VCM(selector + 1); struct iio_dev *indio_dev = rdev_get_drvdata(rdev); struct ad7768_state *st = iio_priv(indio_dev); int ret; if (!iio_device_claim_direct(indio_dev)) return -EBUSY; ret = regmap_update_bits(st->regmap, AD7768_REG_ANALOG2, AD7768_REG_ANALOG2_VCM_MSK, regval); iio_device_release_direct(indio_dev); if (ret) return ret; st->vcm_output_sel = selector; return 0; } static int ad7768_get_voltage_sel(struct regulator_dev *rdev) { struct iio_dev *indio_dev = rdev_get_drvdata(rdev); struct ad7768_state *st = iio_priv(indio_dev); int ret, val; if (!iio_device_claim_direct(indio_dev)) return -EBUSY; ret = regmap_read(st->regmap, AD7768_REG_ANALOG2, &val); iio_device_release_direct(indio_dev); if (ret) return ret; val = FIELD_GET(AD7768_REG_ANALOG2_VCM_MSK, val); return clamp(val, 1, rdev->desc->n_voltages) - 1; } static const struct regulator_ops vcm_regulator_ops = { .enable = ad7768_vcm_enable, .disable = ad7768_vcm_disable, .is_enabled = ad7768_vcm_is_enabled, .list_voltage = regulator_list_voltage_table, .set_voltage_sel = ad7768_set_voltage_sel, .get_voltage_sel = ad7768_get_voltage_sel, }; static const unsigned int vcm_voltage_table[] = { 2500000, 2050000, 1650000, 1900000, 1100000, 900000, }; static const struct regulator_desc vcm_desc = { .name = "ad7768-1-vcm", .of_match = "vcm-output", .regulators_node = "regulators", .n_voltages = ARRAY_SIZE(vcm_voltage_table), .volt_table = vcm_voltage_table, .ops = &vcm_regulator_ops, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }; static int ad7768_register_vcm_regulator(struct device *dev, struct ad7768_state *st, struct iio_dev *indio_dev) { struct regulator_config config = { .dev = dev, .driver_data = indio_dev, }; int ret; /* Disable the regulator before registering it */ ret = regmap_update_bits(st->regmap, AD7768_REG_ANALOG2, AD7768_REG_ANALOG2_VCM_MSK, AD7768_VCM_OFF); if (ret) return ret; st->vcm_rdev = devm_regulator_register(dev, &vcm_desc, &config); if (IS_ERR(st->vcm_rdev)) return dev_err_probe(dev, PTR_ERR(st->vcm_rdev), "failed to register VCM regulator\n"); return 0; } static int ad7768_parse_aaf_gain(struct device *dev, struct ad7768_state *st) { u32 val; int ret; ret = device_property_read_u32(dev, "adi,aaf-gain-bp", &val); if (ret == -EINVAL) { /* If controllable, use default */ if (st->chip->has_variable_aaf) st->aaf_gain = AD7768_AAF_IN1; return 0; } if (ret) return dev_err_probe(dev, ret, "Failed to get AAF gain value\n"); if (!st->chip->has_variable_aaf) return dev_err_probe(dev, -EOPNOTSUPP, "AAF gain provided, but not supported for %s\n", st->chip->name); switch (val) { case 10000: st->aaf_gain = AD7768_AAF_IN1; break; case 3640: st->aaf_gain = AD7768_AAF_IN2; break; case 1430: st->aaf_gain = AD7768_AAF_IN3; break; default: return dev_err_probe(dev, -EINVAL, "Invalid firmware provided AAF gain\n"); } return 0; } static const struct ad7768_chip_info ad7768_chip_info = { .name = "ad7768-1", .channel_spec = ad7768_channels, .num_channels = ARRAY_SIZE(ad7768_channels), .has_vcm_regulator = true, }; static const struct ad7768_chip_info adaq7767_chip_info = { .name = "adaq7767-1", .channel_spec = ad7768_channels, .num_channels = ARRAY_SIZE(ad7768_channels), .has_variable_aaf = true, }; static const struct ad7768_chip_info adaq7768_chip_info = { .name = "adaq7768-1", .channel_spec = adaq776x_channels, .num_channels = ARRAY_SIZE(adaq776x_channels), .pga_gains = adaq7768_gains, .default_pga_mode = AD7768_PGA_GAIN_2, .num_pga_modes = ARRAY_SIZE(adaq7768_gains), .pgia_mode2pin_offset = 6, .has_pga = true, }; static const struct ad7768_chip_info adaq7769_chip_info = { .name = "adaq7769-1", .channel_spec = adaq776x_channels, .num_channels = ARRAY_SIZE(adaq776x_channels), .pga_gains = adaq7769_gains, .default_pga_mode = AD7768_PGA_GAIN_0, .num_pga_modes = ARRAY_SIZE(adaq7769_gains), .pgia_mode2pin_offset = 0, .has_pga = true, .has_variable_aaf = true, }; static int ad7768_probe(struct spi_device *spi) { struct ad7768_state *st; struct iio_dev *indio_dev; int ret; indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); if (!indio_dev) return -ENOMEM; st = iio_priv(indio_dev); /* * Datasheet recommends SDI line to be kept high when data is not being * clocked out of the controller and the spi clock is free running, * to prevent accidental reset. * Since many controllers do not support the SPI_MOSI_IDLE_HIGH flag * yet, only request the MOSI idle state to enable if the controller * supports it. */ if (spi->controller->mode_bits & SPI_MOSI_IDLE_HIGH) { spi->mode |= SPI_MOSI_IDLE_HIGH; ret = spi_setup(spi); if (ret < 0) return ret; } st->chip = spi_get_device_match_data(spi); st->spi = spi; st->regmap = devm_regmap_init_spi(spi, &ad7768_regmap_config); if (IS_ERR(st->regmap)) return dev_err_probe(&spi->dev, PTR_ERR(st->regmap), "Failed to initialize regmap"); st->regmap24 = devm_regmap_init_spi(spi, &ad7768_regmap24_config); if (IS_ERR(st->regmap24)) return dev_err_probe(&spi->dev, PTR_ERR(st->regmap24), "Failed to initialize regmap24"); ret = devm_regulator_get_enable_read_voltage(&spi->dev, "vref"); if (ret < 0) return dev_err_probe(&spi->dev, ret, "Failed to get VREF voltage\n"); st->vref_uv = ret; st->mclk = devm_clk_get_enabled(&spi->dev, "mclk"); if (IS_ERR(st->mclk)) return PTR_ERR(st->mclk); st->mclk_freq = clk_get_rate(st->mclk); indio_dev->channels = st->chip->channel_spec; indio_dev->num_channels = st->chip->num_channels; indio_dev->name = st->chip->name; indio_dev->info = &ad7768_info; indio_dev->modes = INDIO_DIRECT_MODE; /* Register VCM output regulator */ if (st->chip->has_vcm_regulator) { ret = ad7768_register_vcm_regulator(&spi->dev, st, indio_dev); if (ret) return ret; } ret = ad7768_parse_aaf_gain(&spi->dev, st); if (ret) return ret; ret = ad7768_setup(indio_dev); if (ret < 0) { dev_err(&spi->dev, "AD7768 setup failed\n"); return ret; } init_completion(&st->completion); ret = devm_mutex_init(&spi->dev, &st->pga_lock); if (ret) return ret; if (st->chip->has_pga) { ret = ad7768_setup_pga(&spi->dev, st); if (ret) return ret; ret = ad7768_set_pga_gain(st, st->chip->default_pga_mode); if (ret) return ret; } ret = ad7768_set_channel_label(indio_dev, st->chip->num_channels); if (ret) return ret; ret = devm_request_irq(&spi->dev, spi->irq, &ad7768_interrupt, IRQF_TRIGGER_RISING | IRQF_NO_THREAD, indio_dev->name, indio_dev); if (ret) return ret; ret = ad7768_triggered_buffer_alloc(indio_dev); if (ret) return ret; return devm_iio_device_register(&spi->dev, indio_dev); } static const struct spi_device_id ad7768_id_table[] = { { "ad7768-1", (kernel_ulong_t)&ad7768_chip_info }, { "adaq7767-1", (kernel_ulong_t)&adaq7767_chip_info }, { "adaq7768-1", (kernel_ulong_t)&adaq7768_chip_info }, { "adaq7769-1", (kernel_ulong_t)&adaq7769_chip_info }, { } }; MODULE_DEVICE_TABLE(spi, ad7768_id_table); static const struct of_device_id ad7768_of_match[] = { { .compatible = "adi,ad7768-1", .data = &ad7768_chip_info }, { .compatible = "adi,adaq7767-1", .data = &adaq7767_chip_info }, { .compatible = "adi,adaq7768-1", .data = &adaq7768_chip_info }, { .compatible = "adi,adaq7769-1", .data = &adaq7769_chip_info }, { } }; MODULE_DEVICE_TABLE(of, ad7768_of_match); static struct spi_driver ad7768_driver = { .driver = { .name = "ad7768-1", .of_match_table = ad7768_of_match, }, .probe = ad7768_probe, .id_table = ad7768_id_table, }; module_spi_driver(ad7768_driver); MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>"); MODULE_DESCRIPTION("Analog Devices AD7768-1 ADC driver"); MODULE_LICENSE("GPL v2");
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with Cregit http://github.com/cregit/cregit
Version 2.0-RC1