16250803fSAntoniu Miclaus // SPDX-License-Identifier: GPL-2.0-only
26250803fSAntoniu Miclaus /*
36250803fSAntoniu Miclaus * Analog Devices AD4851 DAS driver
46250803fSAntoniu Miclaus *
56250803fSAntoniu Miclaus * Copyright 2024 Analog Devices Inc.
66250803fSAntoniu Miclaus */
76250803fSAntoniu Miclaus
86250803fSAntoniu Miclaus #include <linux/array_size.h>
96250803fSAntoniu Miclaus #include <linux/bitfield.h>
106250803fSAntoniu Miclaus #include <linux/bits.h>
116250803fSAntoniu Miclaus #include <linux/delay.h>
126250803fSAntoniu Miclaus #include <linux/device.h>
136250803fSAntoniu Miclaus #include <linux/err.h>
146250803fSAntoniu Miclaus #include <linux/minmax.h>
156250803fSAntoniu Miclaus #include <linux/mod_devicetable.h>
166250803fSAntoniu Miclaus #include <linux/module.h>
176250803fSAntoniu Miclaus #include <linux/mutex.h>
186250803fSAntoniu Miclaus #include <linux/pwm.h>
196250803fSAntoniu Miclaus #include <linux/regmap.h>
206250803fSAntoniu Miclaus #include <linux/regulator/consumer.h>
216250803fSAntoniu Miclaus #include <linux/spi/spi.h>
226250803fSAntoniu Miclaus #include <linux/types.h>
236250803fSAntoniu Miclaus #include <linux/unaligned.h>
246250803fSAntoniu Miclaus #include <linux/units.h>
256250803fSAntoniu Miclaus
266250803fSAntoniu Miclaus #include <linux/iio/backend.h>
276250803fSAntoniu Miclaus #include <linux/iio/iio.h>
286250803fSAntoniu Miclaus
296250803fSAntoniu Miclaus #define AD4851_REG_INTERFACE_CONFIG_A 0x00
306250803fSAntoniu Miclaus #define AD4851_REG_INTERFACE_CONFIG_B 0x01
316250803fSAntoniu Miclaus #define AD4851_REG_PRODUCT_ID_L 0x04
326250803fSAntoniu Miclaus #define AD4851_REG_PRODUCT_ID_H 0x05
336250803fSAntoniu Miclaus #define AD4851_REG_DEVICE_CTRL 0x25
346250803fSAntoniu Miclaus #define AD4851_REG_PACKET 0x26
356250803fSAntoniu Miclaus #define AD4851_REG_OVERSAMPLE 0x27
366250803fSAntoniu Miclaus
376250803fSAntoniu Miclaus #define AD4851_REG_CH_CONFIG_BASE 0x2A
386250803fSAntoniu Miclaus #define AD4851_REG_CHX_SOFTSPAN(ch) ((0x12 * (ch)) + AD4851_REG_CH_CONFIG_BASE)
396250803fSAntoniu Miclaus #define AD4851_REG_CHX_OFFSET(ch) (AD4851_REG_CHX_SOFTSPAN(ch) + 0x01)
406250803fSAntoniu Miclaus #define AD4851_REG_CHX_OFFSET_LSB(ch) AD4851_REG_CHX_OFFSET(ch)
416250803fSAntoniu Miclaus #define AD4851_REG_CHX_OFFSET_MID(ch) (AD4851_REG_CHX_OFFSET_LSB(ch) + 0x01)
426250803fSAntoniu Miclaus #define AD4851_REG_CHX_OFFSET_MSB(ch) (AD4851_REG_CHX_OFFSET_MID(ch) + 0x01)
436250803fSAntoniu Miclaus #define AD4851_REG_CHX_GAIN(ch) (AD4851_REG_CHX_OFFSET(ch) + 0x03)
446250803fSAntoniu Miclaus #define AD4851_REG_CHX_GAIN_LSB(ch) AD4851_REG_CHX_GAIN(ch)
456250803fSAntoniu Miclaus #define AD4851_REG_CHX_GAIN_MSB(ch) (AD4851_REG_CHX_GAIN(ch) + 0x01)
466250803fSAntoniu Miclaus #define AD4851_REG_CHX_PHASE(ch) (AD4851_REG_CHX_GAIN(ch) + 0x02)
476250803fSAntoniu Miclaus #define AD4851_REG_CHX_PHASE_LSB(ch) AD4851_REG_CHX_PHASE(ch)
486250803fSAntoniu Miclaus #define AD4851_REG_CHX_PHASE_MSB(ch) (AD4851_REG_CHX_PHASE_LSB(ch) + 0x01)
496250803fSAntoniu Miclaus
506250803fSAntoniu Miclaus #define AD4851_REG_TESTPAT_0(c) (0x38 + (c) * 0x12)
516250803fSAntoniu Miclaus #define AD4851_REG_TESTPAT_1(c) (0x39 + (c) * 0x12)
526250803fSAntoniu Miclaus #define AD4851_REG_TESTPAT_2(c) (0x3A + (c) * 0x12)
536250803fSAntoniu Miclaus #define AD4851_REG_TESTPAT_3(c) (0x3B + (c) * 0x12)
546250803fSAntoniu Miclaus
556250803fSAntoniu Miclaus #define AD4851_SW_RESET (BIT(7) | BIT(0))
566250803fSAntoniu Miclaus #define AD4851_SDO_ENABLE BIT(4)
576250803fSAntoniu Miclaus #define AD4851_SINGLE_INSTRUCTION BIT(7)
586250803fSAntoniu Miclaus #define AD4851_REFBUF BIT(2)
596250803fSAntoniu Miclaus #define AD4851_REFSEL BIT(1)
606250803fSAntoniu Miclaus #define AD4851_ECHO_CLOCK_MODE BIT(0)
616250803fSAntoniu Miclaus
626250803fSAntoniu Miclaus #define AD4851_PACKET_FORMAT_0 0
636250803fSAntoniu Miclaus #define AD4851_PACKET_FORMAT_1 1
646250803fSAntoniu Miclaus #define AD4851_PACKET_FORMAT_MASK GENMASK(1, 0)
656250803fSAntoniu Miclaus
666250803fSAntoniu Miclaus #define AD4851_OS_EN_MSK BIT(7)
676250803fSAntoniu Miclaus #define AD4851_OS_RATIO_MSK GENMASK(3, 0)
686250803fSAntoniu Miclaus
696250803fSAntoniu Miclaus #define AD4851_TEST_PAT BIT(2)
706250803fSAntoniu Miclaus
716250803fSAntoniu Miclaus #define AD4858_PACKET_SIZE_20 0
726250803fSAntoniu Miclaus #define AD4858_PACKET_SIZE_24 1
736250803fSAntoniu Miclaus #define AD4858_PACKET_SIZE_32 2
746250803fSAntoniu Miclaus
756250803fSAntoniu Miclaus #define AD4857_PACKET_SIZE_16 0
766250803fSAntoniu Miclaus #define AD4857_PACKET_SIZE_24 1
776250803fSAntoniu Miclaus
786250803fSAntoniu Miclaus #define AD4851_TESTPAT_0_DEFAULT 0x2A
796250803fSAntoniu Miclaus #define AD4851_TESTPAT_1_DEFAULT 0x3C
806250803fSAntoniu Miclaus #define AD4851_TESTPAT_2_DEFAULT 0xCE
816250803fSAntoniu Miclaus #define AD4851_TESTPAT_3_DEFAULT(c) (0x0A + (0x10 * (c)))
826250803fSAntoniu Miclaus
836250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_0V_2V5 0
846250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_N2V5_2V5 1
856250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_0V_5V 2
866250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_N5V_5V 3
876250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_0V_6V25 4
886250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_N6V25_6V25 5
896250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_0V_10V 6
906250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_N10V_10V 7
916250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_0V_12V5 8
926250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_N12V5_12V5 9
936250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_0V_20V 10
946250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_N20V_20V 11
956250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_0V_25V 12
966250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_N25V_25V 13
976250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_0V_40V 14
986250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_N40V_40V 15
996250803fSAntoniu Miclaus
1006250803fSAntoniu Miclaus #define AD4851_MAX_LANES 8
1016250803fSAntoniu Miclaus #define AD4851_MAX_IODELAY 32
1026250803fSAntoniu Miclaus
1036250803fSAntoniu Miclaus #define AD4851_T_CNVH_NS 40
1046250803fSAntoniu Miclaus #define AD4851_T_CNVH_NS_MARGIN 10
1056250803fSAntoniu Miclaus
1066250803fSAntoniu Miclaus #define AD4841_MAX_SCALE_AVAIL 8
1076250803fSAntoniu Miclaus
1086250803fSAntoniu Miclaus #define AD4851_MAX_CH_NR 8
1096250803fSAntoniu Miclaus #define AD4851_CH_START 0
1106250803fSAntoniu Miclaus
1116250803fSAntoniu Miclaus struct ad4851_scale {
1126250803fSAntoniu Miclaus unsigned int scale_val;
1136250803fSAntoniu Miclaus u8 reg_val;
1146250803fSAntoniu Miclaus };
1156250803fSAntoniu Miclaus
1166250803fSAntoniu Miclaus static const struct ad4851_scale ad4851_scale_table_unipolar[] = {
1176250803fSAntoniu Miclaus { 2500, 0x0 },
1186250803fSAntoniu Miclaus { 5000, 0x2 },
1196250803fSAntoniu Miclaus { 6250, 0x4 },
1206250803fSAntoniu Miclaus { 10000, 0x6 },
1216250803fSAntoniu Miclaus { 12500, 0x8 },
1226250803fSAntoniu Miclaus { 20000, 0xA },
1236250803fSAntoniu Miclaus { 25000, 0xC },
1246250803fSAntoniu Miclaus { 40000, 0xE },
1256250803fSAntoniu Miclaus };
1266250803fSAntoniu Miclaus
1276250803fSAntoniu Miclaus static const struct ad4851_scale ad4851_scale_table_bipolar[] = {
1286250803fSAntoniu Miclaus { 5000, 0x1 },
1296250803fSAntoniu Miclaus { 10000, 0x3 },
1306250803fSAntoniu Miclaus { 12500, 0x5 },
1316250803fSAntoniu Miclaus { 20000, 0x7 },
1326250803fSAntoniu Miclaus { 25000, 0x9 },
1336250803fSAntoniu Miclaus { 40000, 0xB },
1346250803fSAntoniu Miclaus { 50000, 0xD },
1356250803fSAntoniu Miclaus { 80000, 0xF },
1366250803fSAntoniu Miclaus };
1376250803fSAntoniu Miclaus
1386250803fSAntoniu Miclaus static const unsigned int ad4851_scale_avail_unipolar[] = {
1396250803fSAntoniu Miclaus 2500,
1406250803fSAntoniu Miclaus 5000,
1416250803fSAntoniu Miclaus 6250,
1426250803fSAntoniu Miclaus 10000,
1436250803fSAntoniu Miclaus 12500,
1446250803fSAntoniu Miclaus 20000,
1456250803fSAntoniu Miclaus 25000,
1466250803fSAntoniu Miclaus 40000,
1476250803fSAntoniu Miclaus };
1486250803fSAntoniu Miclaus
1496250803fSAntoniu Miclaus static const unsigned int ad4851_scale_avail_bipolar[] = {
1506250803fSAntoniu Miclaus 5000,
1516250803fSAntoniu Miclaus 10000,
1526250803fSAntoniu Miclaus 12500,
1536250803fSAntoniu Miclaus 20000,
1546250803fSAntoniu Miclaus 25000,
1556250803fSAntoniu Miclaus 40000,
1566250803fSAntoniu Miclaus 50000,
1576250803fSAntoniu Miclaus 80000,
1586250803fSAntoniu Miclaus };
1596250803fSAntoniu Miclaus
1606250803fSAntoniu Miclaus struct ad4851_chip_info {
1616250803fSAntoniu Miclaus const char *name;
1626250803fSAntoniu Miclaus unsigned int product_id;
1636250803fSAntoniu Miclaus int num_scales;
1646250803fSAntoniu Miclaus unsigned long max_sample_rate_hz;
1656250803fSAntoniu Miclaus unsigned int resolution;
1666250803fSAntoniu Miclaus unsigned int max_channels;
1676250803fSAntoniu Miclaus int (*parse_channels)(struct iio_dev *indio_dev);
1686250803fSAntoniu Miclaus };
1696250803fSAntoniu Miclaus
1706250803fSAntoniu Miclaus enum {
1716250803fSAntoniu Miclaus AD4851_SCAN_TYPE_NORMAL,
1726250803fSAntoniu Miclaus AD4851_SCAN_TYPE_RESOLUTION_BOOST,
1736250803fSAntoniu Miclaus };
1746250803fSAntoniu Miclaus
1756250803fSAntoniu Miclaus struct ad4851_state {
1766250803fSAntoniu Miclaus struct spi_device *spi;
1776250803fSAntoniu Miclaus struct pwm_device *cnv;
1786250803fSAntoniu Miclaus struct iio_backend *back;
1796250803fSAntoniu Miclaus /*
1806250803fSAntoniu Miclaus * Synchronize access to members the of driver state, and ensure
1816250803fSAntoniu Miclaus * atomicity of consecutive regmap operations.
1826250803fSAntoniu Miclaus */
1836250803fSAntoniu Miclaus struct mutex lock;
1846250803fSAntoniu Miclaus struct regmap *regmap;
1856250803fSAntoniu Miclaus const struct ad4851_chip_info *info;
1866250803fSAntoniu Miclaus struct gpio_desc *pd_gpio;
1876250803fSAntoniu Miclaus bool resolution_boost_enabled;
1886250803fSAntoniu Miclaus unsigned long cnv_trigger_rate_hz;
1896250803fSAntoniu Miclaus unsigned int osr;
1906250803fSAntoniu Miclaus bool vrefbuf_en;
1916250803fSAntoniu Miclaus bool vrefio_en;
1926250803fSAntoniu Miclaus bool bipolar_ch[AD4851_MAX_CH_NR];
1936250803fSAntoniu Miclaus unsigned int scales_unipolar[AD4841_MAX_SCALE_AVAIL][2];
1946250803fSAntoniu Miclaus unsigned int scales_bipolar[AD4841_MAX_SCALE_AVAIL][2];
1956250803fSAntoniu Miclaus };
1966250803fSAntoniu Miclaus
ad4851_reg_access(struct iio_dev * indio_dev,unsigned int reg,unsigned int writeval,unsigned int * readval)1976250803fSAntoniu Miclaus static int ad4851_reg_access(struct iio_dev *indio_dev,
1986250803fSAntoniu Miclaus unsigned int reg,
1996250803fSAntoniu Miclaus unsigned int writeval,
2006250803fSAntoniu Miclaus unsigned int *readval)
2016250803fSAntoniu Miclaus {
2026250803fSAntoniu Miclaus struct ad4851_state *st = iio_priv(indio_dev);
2036250803fSAntoniu Miclaus
2046250803fSAntoniu Miclaus if (readval)
2056250803fSAntoniu Miclaus return regmap_read(st->regmap, reg, readval);
2066250803fSAntoniu Miclaus
2076250803fSAntoniu Miclaus return regmap_write(st->regmap, reg, writeval);
2086250803fSAntoniu Miclaus }
2096250803fSAntoniu Miclaus
ad4851_set_sampling_freq(struct ad4851_state * st,unsigned int freq)2106250803fSAntoniu Miclaus static int ad4851_set_sampling_freq(struct ad4851_state *st, unsigned int freq)
2116250803fSAntoniu Miclaus {
2126250803fSAntoniu Miclaus struct pwm_state cnv_state = {
2136250803fSAntoniu Miclaus .duty_cycle = AD4851_T_CNVH_NS + AD4851_T_CNVH_NS_MARGIN,
2146250803fSAntoniu Miclaus .enabled = true,
2156250803fSAntoniu Miclaus };
2166250803fSAntoniu Miclaus int ret;
2176250803fSAntoniu Miclaus
2186250803fSAntoniu Miclaus freq = clamp(freq, 1, st->info->max_sample_rate_hz);
2196250803fSAntoniu Miclaus
2206250803fSAntoniu Miclaus cnv_state.period = DIV_ROUND_UP_ULL(NSEC_PER_SEC, freq);
2216250803fSAntoniu Miclaus
2226250803fSAntoniu Miclaus ret = pwm_apply_might_sleep(st->cnv, &cnv_state);
2236250803fSAntoniu Miclaus if (ret)
2246250803fSAntoniu Miclaus return ret;
2256250803fSAntoniu Miclaus
2266250803fSAntoniu Miclaus st->cnv_trigger_rate_hz = freq;
2276250803fSAntoniu Miclaus
2286250803fSAntoniu Miclaus return 0;
2296250803fSAntoniu Miclaus }
2306250803fSAntoniu Miclaus
2316250803fSAntoniu Miclaus static const int ad4851_oversampling_ratios[] = {
2326250803fSAntoniu Miclaus 1, 2, 4, 8, 16, 32, 64, 128,
2336250803fSAntoniu Miclaus 256, 512, 1024, 2048, 4096, 8192, 16384, 32768,
2346250803fSAntoniu Miclaus 65536,
2356250803fSAntoniu Miclaus };
2366250803fSAntoniu Miclaus
ad4851_osr_to_regval(unsigned int ratio)2376250803fSAntoniu Miclaus static int ad4851_osr_to_regval(unsigned int ratio)
2386250803fSAntoniu Miclaus {
2396250803fSAntoniu Miclaus int i;
2406250803fSAntoniu Miclaus
2416250803fSAntoniu Miclaus for (i = 1; i < ARRAY_SIZE(ad4851_oversampling_ratios); i++)
2426250803fSAntoniu Miclaus if (ratio == ad4851_oversampling_ratios[i])
2436250803fSAntoniu Miclaus return i - 1;
2446250803fSAntoniu Miclaus
2456250803fSAntoniu Miclaus return -EINVAL;
2466250803fSAntoniu Miclaus }
2476250803fSAntoniu Miclaus
__ad4851_get_scale(struct iio_dev * indio_dev,int scale_tbl,unsigned int * val,unsigned int * val2)2486250803fSAntoniu Miclaus static int __ad4851_get_scale(struct iio_dev *indio_dev, int scale_tbl,
2496250803fSAntoniu Miclaus unsigned int *val, unsigned int *val2)
2506250803fSAntoniu Miclaus {
2516250803fSAntoniu Miclaus const struct iio_scan_type *scan_type;
2526250803fSAntoniu Miclaus unsigned int tmp;
2536250803fSAntoniu Miclaus
2546250803fSAntoniu Miclaus scan_type = iio_get_current_scan_type(indio_dev, &indio_dev->channels[0]);
2556250803fSAntoniu Miclaus if (IS_ERR(scan_type))
2566250803fSAntoniu Miclaus return PTR_ERR(scan_type);
2576250803fSAntoniu Miclaus
2586250803fSAntoniu Miclaus tmp = ((u64)scale_tbl * MICRO) >> scan_type->realbits;
2596250803fSAntoniu Miclaus *val = tmp / MICRO;
2606250803fSAntoniu Miclaus *val2 = tmp % MICRO;
2616250803fSAntoniu Miclaus
2626250803fSAntoniu Miclaus return 0;
2636250803fSAntoniu Miclaus }
2646250803fSAntoniu Miclaus
ad4851_scale_fill(struct iio_dev * indio_dev)2656250803fSAntoniu Miclaus static int ad4851_scale_fill(struct iio_dev *indio_dev)
2666250803fSAntoniu Miclaus {
2676250803fSAntoniu Miclaus struct ad4851_state *st = iio_priv(indio_dev);
2686250803fSAntoniu Miclaus unsigned int i, val1, val2;
2696250803fSAntoniu Miclaus int ret;
2706250803fSAntoniu Miclaus
2716250803fSAntoniu Miclaus for (i = 0; i < ARRAY_SIZE(ad4851_scale_avail_unipolar); i++) {
2726250803fSAntoniu Miclaus ret = __ad4851_get_scale(indio_dev,
2736250803fSAntoniu Miclaus ad4851_scale_avail_unipolar[i],
2746250803fSAntoniu Miclaus &val1, &val2);
2756250803fSAntoniu Miclaus if (ret)
2766250803fSAntoniu Miclaus return ret;
2776250803fSAntoniu Miclaus
2786250803fSAntoniu Miclaus st->scales_unipolar[i][0] = val1;
2796250803fSAntoniu Miclaus st->scales_unipolar[i][1] = val2;
2806250803fSAntoniu Miclaus }
2816250803fSAntoniu Miclaus
2826250803fSAntoniu Miclaus for (i = 0; i < ARRAY_SIZE(ad4851_scale_avail_bipolar); i++) {
2836250803fSAntoniu Miclaus ret = __ad4851_get_scale(indio_dev,
2846250803fSAntoniu Miclaus ad4851_scale_avail_bipolar[i],
2856250803fSAntoniu Miclaus &val1, &val2);
2866250803fSAntoniu Miclaus if (ret)
2876250803fSAntoniu Miclaus return ret;
2886250803fSAntoniu Miclaus
2896250803fSAntoniu Miclaus st->scales_bipolar[i][0] = val1;
2906250803fSAntoniu Miclaus st->scales_bipolar[i][1] = val2;
2916250803fSAntoniu Miclaus }
2926250803fSAntoniu Miclaus
2936250803fSAntoniu Miclaus return 0;
2946250803fSAntoniu Miclaus }
2956250803fSAntoniu Miclaus
ad4851_set_oversampling_ratio(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,unsigned int osr)2966250803fSAntoniu Miclaus static int ad4851_set_oversampling_ratio(struct iio_dev *indio_dev,
2976250803fSAntoniu Miclaus const struct iio_chan_spec *chan,
2986250803fSAntoniu Miclaus unsigned int osr)
2996250803fSAntoniu Miclaus {
3006250803fSAntoniu Miclaus struct ad4851_state *st = iio_priv(indio_dev);
3016250803fSAntoniu Miclaus int val, ret;
3026250803fSAntoniu Miclaus
3036250803fSAntoniu Miclaus guard(mutex)(&st->lock);
3046250803fSAntoniu Miclaus
3056250803fSAntoniu Miclaus if (osr == 1) {
3066250803fSAntoniu Miclaus ret = regmap_clear_bits(st->regmap, AD4851_REG_OVERSAMPLE,
3076250803fSAntoniu Miclaus AD4851_OS_EN_MSK);
3086250803fSAntoniu Miclaus if (ret)
3096250803fSAntoniu Miclaus return ret;
3106250803fSAntoniu Miclaus } else {
3116250803fSAntoniu Miclaus val = ad4851_osr_to_regval(osr);
3126250803fSAntoniu Miclaus if (val < 0)
3136250803fSAntoniu Miclaus return -EINVAL;
3146250803fSAntoniu Miclaus
3156250803fSAntoniu Miclaus ret = regmap_update_bits(st->regmap, AD4851_REG_OVERSAMPLE,
3166250803fSAntoniu Miclaus AD4851_OS_EN_MSK |
3176250803fSAntoniu Miclaus AD4851_OS_RATIO_MSK,
3186250803fSAntoniu Miclaus FIELD_PREP(AD4851_OS_EN_MSK, 1) |
3196250803fSAntoniu Miclaus FIELD_PREP(AD4851_OS_RATIO_MSK, val));
3206250803fSAntoniu Miclaus if (ret)
3216250803fSAntoniu Miclaus return ret;
3226250803fSAntoniu Miclaus }
3236250803fSAntoniu Miclaus
3246250803fSAntoniu Miclaus ret = iio_backend_oversampling_ratio_set(st->back, osr);
3256250803fSAntoniu Miclaus if (ret)
3266250803fSAntoniu Miclaus return ret;
3276250803fSAntoniu Miclaus
3286250803fSAntoniu Miclaus switch (st->info->resolution) {
3296250803fSAntoniu Miclaus case 20:
3306250803fSAntoniu Miclaus switch (osr) {
3316250803fSAntoniu Miclaus case 0:
3326250803fSAntoniu Miclaus return -EINVAL;
3336250803fSAntoniu Miclaus case 1:
3346250803fSAntoniu Miclaus val = 20;
3356250803fSAntoniu Miclaus break;
3366250803fSAntoniu Miclaus default:
3376250803fSAntoniu Miclaus val = 24;
3386250803fSAntoniu Miclaus break;
3396250803fSAntoniu Miclaus }
3406250803fSAntoniu Miclaus break;
3416250803fSAntoniu Miclaus case 16:
3426250803fSAntoniu Miclaus val = 16;
3436250803fSAntoniu Miclaus break;
3446250803fSAntoniu Miclaus default:
3456250803fSAntoniu Miclaus return -EINVAL;
3466250803fSAntoniu Miclaus }
3476250803fSAntoniu Miclaus
3486250803fSAntoniu Miclaus ret = iio_backend_data_size_set(st->back, val);
3496250803fSAntoniu Miclaus if (ret)
3506250803fSAntoniu Miclaus return ret;
3516250803fSAntoniu Miclaus
3526250803fSAntoniu Miclaus if (osr == 1 || st->info->resolution == 16) {
3536250803fSAntoniu Miclaus ret = regmap_clear_bits(st->regmap, AD4851_REG_PACKET,
3546250803fSAntoniu Miclaus AD4851_PACKET_FORMAT_MASK);
3556250803fSAntoniu Miclaus if (ret)
3566250803fSAntoniu Miclaus return ret;
3576250803fSAntoniu Miclaus
3586250803fSAntoniu Miclaus st->resolution_boost_enabled = false;
3596250803fSAntoniu Miclaus } else {
3606250803fSAntoniu Miclaus ret = regmap_update_bits(st->regmap, AD4851_REG_PACKET,
3616250803fSAntoniu Miclaus AD4851_PACKET_FORMAT_MASK,
3626250803fSAntoniu Miclaus FIELD_PREP(AD4851_PACKET_FORMAT_MASK, 1));
3636250803fSAntoniu Miclaus if (ret)
3646250803fSAntoniu Miclaus return ret;
3656250803fSAntoniu Miclaus
3666250803fSAntoniu Miclaus st->resolution_boost_enabled = true;
3676250803fSAntoniu Miclaus }
3686250803fSAntoniu Miclaus
3696250803fSAntoniu Miclaus if (st->osr != osr) {
3706250803fSAntoniu Miclaus ret = ad4851_scale_fill(indio_dev);
3716250803fSAntoniu Miclaus if (ret)
3726250803fSAntoniu Miclaus return ret;
3736250803fSAntoniu Miclaus
3746250803fSAntoniu Miclaus st->osr = osr;
3756250803fSAntoniu Miclaus }
3766250803fSAntoniu Miclaus
3776250803fSAntoniu Miclaus return 0;
3786250803fSAntoniu Miclaus }
3796250803fSAntoniu Miclaus
ad4851_get_oversampling_ratio(struct ad4851_state * st,unsigned int * val)3806250803fSAntoniu Miclaus static int ad4851_get_oversampling_ratio(struct ad4851_state *st, unsigned int *val)
3816250803fSAntoniu Miclaus {
3826250803fSAntoniu Miclaus unsigned int osr;
3836250803fSAntoniu Miclaus int ret;
3846250803fSAntoniu Miclaus
3856250803fSAntoniu Miclaus guard(mutex)(&st->lock);
3866250803fSAntoniu Miclaus
3876250803fSAntoniu Miclaus ret = regmap_read(st->regmap, AD4851_REG_OVERSAMPLE, &osr);
3886250803fSAntoniu Miclaus if (ret)
3896250803fSAntoniu Miclaus return ret;
3906250803fSAntoniu Miclaus
3916250803fSAntoniu Miclaus if (!FIELD_GET(AD4851_OS_EN_MSK, osr))
3926250803fSAntoniu Miclaus *val = 1;
3936250803fSAntoniu Miclaus else
3946250803fSAntoniu Miclaus *val = ad4851_oversampling_ratios[FIELD_GET(AD4851_OS_RATIO_MSK, osr) + 1];
3956250803fSAntoniu Miclaus
3966250803fSAntoniu Miclaus st->osr = *val;
3976250803fSAntoniu Miclaus
3986250803fSAntoniu Miclaus return IIO_VAL_INT;
3996250803fSAntoniu Miclaus }
4006250803fSAntoniu Miclaus
ad4851_pwm_disable(void * data)4016250803fSAntoniu Miclaus static void ad4851_pwm_disable(void *data)
4026250803fSAntoniu Miclaus {
4036250803fSAntoniu Miclaus pwm_disable(data);
4046250803fSAntoniu Miclaus }
4056250803fSAntoniu Miclaus
ad4851_setup(struct ad4851_state * st)4066250803fSAntoniu Miclaus static int ad4851_setup(struct ad4851_state *st)
4076250803fSAntoniu Miclaus {
4086250803fSAntoniu Miclaus unsigned int product_id;
4096250803fSAntoniu Miclaus int ret;
4106250803fSAntoniu Miclaus
4116250803fSAntoniu Miclaus if (st->pd_gpio) {
4126250803fSAntoniu Miclaus /* To initiate a global reset, bring the PD pin high twice */
4136250803fSAntoniu Miclaus gpiod_set_value(st->pd_gpio, 1);
4146250803fSAntoniu Miclaus fsleep(1);
4156250803fSAntoniu Miclaus gpiod_set_value(st->pd_gpio, 0);
4166250803fSAntoniu Miclaus fsleep(1);
4176250803fSAntoniu Miclaus gpiod_set_value(st->pd_gpio, 1);
4186250803fSAntoniu Miclaus fsleep(1);
4196250803fSAntoniu Miclaus gpiod_set_value(st->pd_gpio, 0);
4206250803fSAntoniu Miclaus fsleep(1000);
4216250803fSAntoniu Miclaus } else {
4226250803fSAntoniu Miclaus ret = regmap_set_bits(st->regmap, AD4851_REG_INTERFACE_CONFIG_A,
4236250803fSAntoniu Miclaus AD4851_SW_RESET);
4246250803fSAntoniu Miclaus if (ret)
4256250803fSAntoniu Miclaus return ret;
4266250803fSAntoniu Miclaus }
4276250803fSAntoniu Miclaus
4286250803fSAntoniu Miclaus if (st->vrefbuf_en) {
4296250803fSAntoniu Miclaus ret = regmap_set_bits(st->regmap, AD4851_REG_DEVICE_CTRL,
4306250803fSAntoniu Miclaus AD4851_REFBUF);
4316250803fSAntoniu Miclaus if (ret)
4326250803fSAntoniu Miclaus return ret;
4336250803fSAntoniu Miclaus }
4346250803fSAntoniu Miclaus
4356250803fSAntoniu Miclaus if (st->vrefio_en) {
4366250803fSAntoniu Miclaus ret = regmap_set_bits(st->regmap, AD4851_REG_DEVICE_CTRL,
4376250803fSAntoniu Miclaus AD4851_REFSEL);
4386250803fSAntoniu Miclaus if (ret)
4396250803fSAntoniu Miclaus return ret;
4406250803fSAntoniu Miclaus }
4416250803fSAntoniu Miclaus
4426250803fSAntoniu Miclaus ret = regmap_write(st->regmap, AD4851_REG_INTERFACE_CONFIG_B,
4436250803fSAntoniu Miclaus AD4851_SINGLE_INSTRUCTION);
4446250803fSAntoniu Miclaus if (ret)
4456250803fSAntoniu Miclaus return ret;
4466250803fSAntoniu Miclaus
4476250803fSAntoniu Miclaus ret = regmap_write(st->regmap, AD4851_REG_INTERFACE_CONFIG_A,
4486250803fSAntoniu Miclaus AD4851_SDO_ENABLE);
4496250803fSAntoniu Miclaus if (ret)
4506250803fSAntoniu Miclaus return ret;
4516250803fSAntoniu Miclaus
4526250803fSAntoniu Miclaus ret = regmap_read(st->regmap, AD4851_REG_PRODUCT_ID_L, &product_id);
4536250803fSAntoniu Miclaus if (ret)
4546250803fSAntoniu Miclaus return ret;
4556250803fSAntoniu Miclaus
4566250803fSAntoniu Miclaus if (product_id != st->info->product_id)
4576250803fSAntoniu Miclaus dev_info(&st->spi->dev, "Unknown product ID: 0x%02X\n",
4586250803fSAntoniu Miclaus product_id);
4596250803fSAntoniu Miclaus
4606250803fSAntoniu Miclaus ret = regmap_set_bits(st->regmap, AD4851_REG_DEVICE_CTRL,
4616250803fSAntoniu Miclaus AD4851_ECHO_CLOCK_MODE);
4626250803fSAntoniu Miclaus if (ret)
4636250803fSAntoniu Miclaus return ret;
4646250803fSAntoniu Miclaus
4656250803fSAntoniu Miclaus return regmap_write(st->regmap, AD4851_REG_PACKET, 0);
4666250803fSAntoniu Miclaus }
4676250803fSAntoniu Miclaus
4686250803fSAntoniu Miclaus /*
4696250803fSAntoniu Miclaus * Find the longest consecutive sequence of false values from field
4706250803fSAntoniu Miclaus * and return starting index.
4716250803fSAntoniu Miclaus */
ad4851_find_opt(const unsigned long * field,unsigned int start,unsigned int nbits,unsigned int * val)4726250803fSAntoniu Miclaus static int ad4851_find_opt(const unsigned long *field, unsigned int start,
4736250803fSAntoniu Miclaus unsigned int nbits, unsigned int *val)
4746250803fSAntoniu Miclaus {
4756250803fSAntoniu Miclaus unsigned int bit = start, end, start_cnt, cnt = 0;
4766250803fSAntoniu Miclaus
4776250803fSAntoniu Miclaus for_each_clear_bitrange_from(bit, end, field, start + nbits) {
4786250803fSAntoniu Miclaus if (end - bit > cnt) {
4796250803fSAntoniu Miclaus cnt = end - bit;
4806250803fSAntoniu Miclaus start_cnt = bit - start;
4816250803fSAntoniu Miclaus }
4826250803fSAntoniu Miclaus }
4836250803fSAntoniu Miclaus
4846250803fSAntoniu Miclaus if (!cnt)
4856250803fSAntoniu Miclaus return -ENOENT;
4866250803fSAntoniu Miclaus
4876250803fSAntoniu Miclaus *val = start_cnt;
4886250803fSAntoniu Miclaus
4896250803fSAntoniu Miclaus return cnt;
4906250803fSAntoniu Miclaus }
4916250803fSAntoniu Miclaus
ad4851_calibrate(struct iio_dev * indio_dev)4926250803fSAntoniu Miclaus static int ad4851_calibrate(struct iio_dev *indio_dev)
4936250803fSAntoniu Miclaus {
4946250803fSAntoniu Miclaus struct ad4851_state *st = iio_priv(indio_dev);
495eb2f9ab1SDan Carpenter unsigned int opt_delay, num_lanes, delay, i, s;
4966250803fSAntoniu Miclaus enum iio_backend_interface_type interface_type;
4976250803fSAntoniu Miclaus DECLARE_BITMAP(pn_status, AD4851_MAX_LANES * AD4851_MAX_IODELAY);
4986250803fSAntoniu Miclaus bool status;
499eb2f9ab1SDan Carpenter int c, ret;
5006250803fSAntoniu Miclaus
5016250803fSAntoniu Miclaus ret = iio_backend_interface_type_get(st->back, &interface_type);
5026250803fSAntoniu Miclaus if (ret)
5036250803fSAntoniu Miclaus return ret;
5046250803fSAntoniu Miclaus
5056250803fSAntoniu Miclaus switch (interface_type) {
5066250803fSAntoniu Miclaus case IIO_BACKEND_INTERFACE_SERIAL_CMOS:
5076250803fSAntoniu Miclaus num_lanes = indio_dev->num_channels;
5086250803fSAntoniu Miclaus break;
5096250803fSAntoniu Miclaus case IIO_BACKEND_INTERFACE_SERIAL_LVDS:
5106250803fSAntoniu Miclaus num_lanes = 1;
5116250803fSAntoniu Miclaus break;
5126250803fSAntoniu Miclaus default:
5136250803fSAntoniu Miclaus return -EINVAL;
5146250803fSAntoniu Miclaus }
5156250803fSAntoniu Miclaus
5166250803fSAntoniu Miclaus if (st->info->resolution == 16) {
5176250803fSAntoniu Miclaus ret = iio_backend_data_size_set(st->back, 24);
5186250803fSAntoniu Miclaus if (ret)
5196250803fSAntoniu Miclaus return ret;
5206250803fSAntoniu Miclaus
5216250803fSAntoniu Miclaus ret = regmap_write(st->regmap, AD4851_REG_PACKET,
5226250803fSAntoniu Miclaus AD4851_TEST_PAT | AD4857_PACKET_SIZE_24);
5236250803fSAntoniu Miclaus if (ret)
5246250803fSAntoniu Miclaus return ret;
5256250803fSAntoniu Miclaus } else {
5266250803fSAntoniu Miclaus ret = iio_backend_data_size_set(st->back, 32);
5276250803fSAntoniu Miclaus if (ret)
5286250803fSAntoniu Miclaus return ret;
5296250803fSAntoniu Miclaus
5306250803fSAntoniu Miclaus ret = regmap_write(st->regmap, AD4851_REG_PACKET,
5316250803fSAntoniu Miclaus AD4851_TEST_PAT | AD4858_PACKET_SIZE_32);
5326250803fSAntoniu Miclaus if (ret)
5336250803fSAntoniu Miclaus return ret;
5346250803fSAntoniu Miclaus }
5356250803fSAntoniu Miclaus
5366250803fSAntoniu Miclaus for (i = 0; i < indio_dev->num_channels; i++) {
5376250803fSAntoniu Miclaus ret = regmap_write(st->regmap, AD4851_REG_TESTPAT_0(i),
5386250803fSAntoniu Miclaus AD4851_TESTPAT_0_DEFAULT);
5396250803fSAntoniu Miclaus if (ret)
5406250803fSAntoniu Miclaus return ret;
5416250803fSAntoniu Miclaus
5426250803fSAntoniu Miclaus ret = regmap_write(st->regmap, AD4851_REG_TESTPAT_1(i),
5436250803fSAntoniu Miclaus AD4851_TESTPAT_1_DEFAULT);
5446250803fSAntoniu Miclaus if (ret)
5456250803fSAntoniu Miclaus return ret;
5466250803fSAntoniu Miclaus
5476250803fSAntoniu Miclaus ret = regmap_write(st->regmap, AD4851_REG_TESTPAT_2(i),
5486250803fSAntoniu Miclaus AD4851_TESTPAT_2_DEFAULT);
5496250803fSAntoniu Miclaus if (ret)
5506250803fSAntoniu Miclaus return ret;
5516250803fSAntoniu Miclaus
5526250803fSAntoniu Miclaus ret = regmap_write(st->regmap, AD4851_REG_TESTPAT_3(i),
5536250803fSAntoniu Miclaus AD4851_TESTPAT_3_DEFAULT(i));
5546250803fSAntoniu Miclaus if (ret)
5556250803fSAntoniu Miclaus return ret;
5566250803fSAntoniu Miclaus
5576250803fSAntoniu Miclaus ret = iio_backend_chan_enable(st->back,
5586250803fSAntoniu Miclaus indio_dev->channels[i].channel);
5596250803fSAntoniu Miclaus if (ret)
5606250803fSAntoniu Miclaus return ret;
5616250803fSAntoniu Miclaus }
5626250803fSAntoniu Miclaus
5636250803fSAntoniu Miclaus for (i = 0; i < num_lanes; i++) {
5646250803fSAntoniu Miclaus for (delay = 0; delay < AD4851_MAX_IODELAY; delay++) {
5656250803fSAntoniu Miclaus ret = iio_backend_iodelay_set(st->back, i, delay);
5666250803fSAntoniu Miclaus if (ret)
5676250803fSAntoniu Miclaus return ret;
5686250803fSAntoniu Miclaus
5696250803fSAntoniu Miclaus ret = iio_backend_chan_status(st->back, i, &status);
5706250803fSAntoniu Miclaus if (ret)
5716250803fSAntoniu Miclaus return ret;
5726250803fSAntoniu Miclaus
5736250803fSAntoniu Miclaus __assign_bit(i * AD4851_MAX_IODELAY + delay, pn_status,
5746250803fSAntoniu Miclaus status);
5756250803fSAntoniu Miclaus }
5766250803fSAntoniu Miclaus }
5776250803fSAntoniu Miclaus
5786250803fSAntoniu Miclaus for (i = 0; i < num_lanes; i++) {
5796250803fSAntoniu Miclaus c = ad4851_find_opt(pn_status, i * AD4851_MAX_IODELAY,
5806250803fSAntoniu Miclaus AD4851_MAX_IODELAY, &s);
5816250803fSAntoniu Miclaus if (c < 0)
5826250803fSAntoniu Miclaus return c;
5836250803fSAntoniu Miclaus
5846250803fSAntoniu Miclaus opt_delay = s + c / 2;
5856250803fSAntoniu Miclaus ret = iio_backend_iodelay_set(st->back, i, opt_delay);
5866250803fSAntoniu Miclaus if (ret)
5876250803fSAntoniu Miclaus return ret;
5886250803fSAntoniu Miclaus }
5896250803fSAntoniu Miclaus
5906250803fSAntoniu Miclaus for (i = 0; i < indio_dev->num_channels; i++) {
5916250803fSAntoniu Miclaus ret = iio_backend_chan_disable(st->back, i);
5926250803fSAntoniu Miclaus if (ret)
5936250803fSAntoniu Miclaus return ret;
5946250803fSAntoniu Miclaus }
5956250803fSAntoniu Miclaus
5966250803fSAntoniu Miclaus ret = iio_backend_data_size_set(st->back, 20);
5976250803fSAntoniu Miclaus if (ret)
5986250803fSAntoniu Miclaus return ret;
5996250803fSAntoniu Miclaus
6006250803fSAntoniu Miclaus return regmap_write(st->regmap, AD4851_REG_PACKET, 0);
6016250803fSAntoniu Miclaus }
6026250803fSAntoniu Miclaus
ad4851_get_calibscale(struct ad4851_state * st,int ch,int * val,int * val2)6036250803fSAntoniu Miclaus static int ad4851_get_calibscale(struct ad4851_state *st, int ch, int *val, int *val2)
6046250803fSAntoniu Miclaus {
6056250803fSAntoniu Miclaus unsigned int reg_val;
6066250803fSAntoniu Miclaus int gain;
6076250803fSAntoniu Miclaus int ret;
6086250803fSAntoniu Miclaus
6096250803fSAntoniu Miclaus guard(mutex)(&st->lock);
6106250803fSAntoniu Miclaus
6116250803fSAntoniu Miclaus ret = regmap_read(st->regmap, AD4851_REG_CHX_GAIN_MSB(ch), ®_val);
6126250803fSAntoniu Miclaus if (ret)
6136250803fSAntoniu Miclaus return ret;
6146250803fSAntoniu Miclaus
6156250803fSAntoniu Miclaus gain = reg_val << 8;
6166250803fSAntoniu Miclaus
6176250803fSAntoniu Miclaus ret = regmap_read(st->regmap, AD4851_REG_CHX_GAIN_LSB(ch), ®_val);
6186250803fSAntoniu Miclaus if (ret)
6196250803fSAntoniu Miclaus return ret;
6206250803fSAntoniu Miclaus
6216250803fSAntoniu Miclaus gain |= reg_val;
6226250803fSAntoniu Miclaus
6236250803fSAntoniu Miclaus *val = gain;
6246250803fSAntoniu Miclaus *val2 = 15;
6256250803fSAntoniu Miclaus
6266250803fSAntoniu Miclaus return IIO_VAL_FRACTIONAL_LOG2;
6276250803fSAntoniu Miclaus }
6286250803fSAntoniu Miclaus
ad4851_set_calibscale(struct ad4851_state * st,int ch,int val,int val2)6296250803fSAntoniu Miclaus static int ad4851_set_calibscale(struct ad4851_state *st, int ch, int val,
6306250803fSAntoniu Miclaus int val2)
6316250803fSAntoniu Miclaus {
6326250803fSAntoniu Miclaus u64 gain;
6336250803fSAntoniu Miclaus u8 buf[2];
6346250803fSAntoniu Miclaus int ret;
6356250803fSAntoniu Miclaus
6366250803fSAntoniu Miclaus if (val < 0 || val2 < 0)
6376250803fSAntoniu Miclaus return -EINVAL;
6386250803fSAntoniu Miclaus
6396250803fSAntoniu Miclaus gain = val * MICRO + val2;
6406250803fSAntoniu Miclaus gain = DIV_U64_ROUND_CLOSEST(gain * 32768, MICRO);
6416250803fSAntoniu Miclaus
6426250803fSAntoniu Miclaus put_unaligned_be16(gain, buf);
6436250803fSAntoniu Miclaus
6446250803fSAntoniu Miclaus guard(mutex)(&st->lock);
6456250803fSAntoniu Miclaus
6466250803fSAntoniu Miclaus ret = regmap_write(st->regmap, AD4851_REG_CHX_GAIN_MSB(ch), buf[0]);
6476250803fSAntoniu Miclaus if (ret)
6486250803fSAntoniu Miclaus return ret;
6496250803fSAntoniu Miclaus
6506250803fSAntoniu Miclaus return regmap_write(st->regmap, AD4851_REG_CHX_GAIN_LSB(ch), buf[1]);
6516250803fSAntoniu Miclaus }
6526250803fSAntoniu Miclaus
ad4851_get_calibbias(struct ad4851_state * st,int ch,int * val)6536250803fSAntoniu Miclaus static int ad4851_get_calibbias(struct ad4851_state *st, int ch, int *val)
6546250803fSAntoniu Miclaus {
6556250803fSAntoniu Miclaus unsigned int lsb, mid, msb;
6566250803fSAntoniu Miclaus int ret;
6576250803fSAntoniu Miclaus
6586250803fSAntoniu Miclaus guard(mutex)(&st->lock);
6596250803fSAntoniu Miclaus /*
6606250803fSAntoniu Miclaus * After testing, the bulk_write operations doesn't work as expected
6616250803fSAntoniu Miclaus * here since the cs needs to be raised after each byte transaction.
6626250803fSAntoniu Miclaus */
6636250803fSAntoniu Miclaus ret = regmap_read(st->regmap, AD4851_REG_CHX_OFFSET_MSB(ch), &msb);
6646250803fSAntoniu Miclaus if (ret)
6656250803fSAntoniu Miclaus return ret;
6666250803fSAntoniu Miclaus
6676250803fSAntoniu Miclaus ret = regmap_read(st->regmap, AD4851_REG_CHX_OFFSET_MID(ch), &mid);
6686250803fSAntoniu Miclaus if (ret)
6696250803fSAntoniu Miclaus return ret;
6706250803fSAntoniu Miclaus
6716250803fSAntoniu Miclaus ret = regmap_read(st->regmap, AD4851_REG_CHX_OFFSET_LSB(ch), &lsb);
6726250803fSAntoniu Miclaus if (ret)
6736250803fSAntoniu Miclaus return ret;
6746250803fSAntoniu Miclaus
6756250803fSAntoniu Miclaus if (st->info->resolution == 16) {
6766250803fSAntoniu Miclaus *val = msb << 8;
6776250803fSAntoniu Miclaus *val |= mid;
6786250803fSAntoniu Miclaus *val = sign_extend32(*val, 15);
6796250803fSAntoniu Miclaus } else {
6806250803fSAntoniu Miclaus *val = msb << 12;
6816250803fSAntoniu Miclaus *val |= mid << 4;
6826250803fSAntoniu Miclaus *val |= lsb >> 4;
6836250803fSAntoniu Miclaus *val = sign_extend32(*val, 19);
6846250803fSAntoniu Miclaus }
6856250803fSAntoniu Miclaus
6866250803fSAntoniu Miclaus return IIO_VAL_INT;
6876250803fSAntoniu Miclaus }
6886250803fSAntoniu Miclaus
ad4851_set_calibbias(struct ad4851_state * st,int ch,int val)6896250803fSAntoniu Miclaus static int ad4851_set_calibbias(struct ad4851_state *st, int ch, int val)
6906250803fSAntoniu Miclaus {
6916250803fSAntoniu Miclaus u8 buf[3];
6926250803fSAntoniu Miclaus int ret;
6936250803fSAntoniu Miclaus
6946250803fSAntoniu Miclaus if (val < 0)
6956250803fSAntoniu Miclaus return -EINVAL;
6966250803fSAntoniu Miclaus
6976250803fSAntoniu Miclaus if (st->info->resolution == 16)
6986250803fSAntoniu Miclaus put_unaligned_be16(val, buf);
6996250803fSAntoniu Miclaus else
7006250803fSAntoniu Miclaus put_unaligned_be24(val << 4, buf);
7016250803fSAntoniu Miclaus
7026250803fSAntoniu Miclaus guard(mutex)(&st->lock);
7036250803fSAntoniu Miclaus /*
7046250803fSAntoniu Miclaus * After testing, the bulk_write operations doesn't work as expected
7056250803fSAntoniu Miclaus * here since the cs needs to be raised after each byte transaction.
7066250803fSAntoniu Miclaus */
7076250803fSAntoniu Miclaus ret = regmap_write(st->regmap, AD4851_REG_CHX_OFFSET_LSB(ch), buf[2]);
7086250803fSAntoniu Miclaus if (ret)
7096250803fSAntoniu Miclaus return ret;
7106250803fSAntoniu Miclaus
7116250803fSAntoniu Miclaus ret = regmap_write(st->regmap, AD4851_REG_CHX_OFFSET_MID(ch), buf[1]);
7126250803fSAntoniu Miclaus if (ret)
7136250803fSAntoniu Miclaus return ret;
7146250803fSAntoniu Miclaus
7156250803fSAntoniu Miclaus return regmap_write(st->regmap, AD4851_REG_CHX_OFFSET_MSB(ch), buf[0]);
7166250803fSAntoniu Miclaus }
7176250803fSAntoniu Miclaus
ad4851_set_scale(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,int val,int val2)7186250803fSAntoniu Miclaus static int ad4851_set_scale(struct iio_dev *indio_dev,
7196250803fSAntoniu Miclaus const struct iio_chan_spec *chan, int val, int val2)
7206250803fSAntoniu Miclaus {
7216250803fSAntoniu Miclaus struct ad4851_state *st = iio_priv(indio_dev);
7226250803fSAntoniu Miclaus unsigned int scale_val[2];
7236250803fSAntoniu Miclaus unsigned int i;
7246250803fSAntoniu Miclaus const struct ad4851_scale *scale_table;
7256250803fSAntoniu Miclaus size_t table_size;
7266250803fSAntoniu Miclaus int ret;
7276250803fSAntoniu Miclaus
7286250803fSAntoniu Miclaus if (st->bipolar_ch[chan->channel]) {
7296250803fSAntoniu Miclaus scale_table = ad4851_scale_table_bipolar;
7306250803fSAntoniu Miclaus table_size = ARRAY_SIZE(ad4851_scale_table_bipolar);
7316250803fSAntoniu Miclaus } else {
7326250803fSAntoniu Miclaus scale_table = ad4851_scale_table_unipolar;
7336250803fSAntoniu Miclaus table_size = ARRAY_SIZE(ad4851_scale_table_unipolar);
7346250803fSAntoniu Miclaus }
7356250803fSAntoniu Miclaus
7366250803fSAntoniu Miclaus for (i = 0; i < table_size; i++) {
7376250803fSAntoniu Miclaus ret = __ad4851_get_scale(indio_dev, scale_table[i].scale_val,
7386250803fSAntoniu Miclaus &scale_val[0], &scale_val[1]);
7396250803fSAntoniu Miclaus if (ret)
7406250803fSAntoniu Miclaus return ret;
7416250803fSAntoniu Miclaus
7426250803fSAntoniu Miclaus if (scale_val[0] != val || scale_val[1] != val2)
7436250803fSAntoniu Miclaus continue;
7446250803fSAntoniu Miclaus
7456250803fSAntoniu Miclaus return regmap_write(st->regmap,
7466250803fSAntoniu Miclaus AD4851_REG_CHX_SOFTSPAN(chan->channel),
7476250803fSAntoniu Miclaus scale_table[i].reg_val);
7486250803fSAntoniu Miclaus }
7496250803fSAntoniu Miclaus
7506250803fSAntoniu Miclaus return -EINVAL;
7516250803fSAntoniu Miclaus }
7526250803fSAntoniu Miclaus
ad4851_get_scale(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,int * val,int * val2)7536250803fSAntoniu Miclaus static int ad4851_get_scale(struct iio_dev *indio_dev,
7546250803fSAntoniu Miclaus const struct iio_chan_spec *chan, int *val,
7556250803fSAntoniu Miclaus int *val2)
7566250803fSAntoniu Miclaus {
7576250803fSAntoniu Miclaus struct ad4851_state *st = iio_priv(indio_dev);
7586250803fSAntoniu Miclaus const struct ad4851_scale *scale_table;
7596250803fSAntoniu Miclaus size_t table_size;
7606250803fSAntoniu Miclaus u32 softspan_val;
7616250803fSAntoniu Miclaus int i, ret;
7626250803fSAntoniu Miclaus
7636250803fSAntoniu Miclaus if (st->bipolar_ch[chan->channel]) {
7646250803fSAntoniu Miclaus scale_table = ad4851_scale_table_bipolar;
7656250803fSAntoniu Miclaus table_size = ARRAY_SIZE(ad4851_scale_table_bipolar);
7666250803fSAntoniu Miclaus } else {
7676250803fSAntoniu Miclaus scale_table = ad4851_scale_table_unipolar;
7686250803fSAntoniu Miclaus table_size = ARRAY_SIZE(ad4851_scale_table_unipolar);
7696250803fSAntoniu Miclaus }
7706250803fSAntoniu Miclaus
7716250803fSAntoniu Miclaus ret = regmap_read(st->regmap, AD4851_REG_CHX_SOFTSPAN(chan->channel),
7726250803fSAntoniu Miclaus &softspan_val);
7736250803fSAntoniu Miclaus if (ret)
7746250803fSAntoniu Miclaus return ret;
7756250803fSAntoniu Miclaus
7766250803fSAntoniu Miclaus for (i = 0; i < table_size; i++) {
7776250803fSAntoniu Miclaus if (softspan_val == scale_table[i].reg_val)
7786250803fSAntoniu Miclaus break;
7796250803fSAntoniu Miclaus }
7806250803fSAntoniu Miclaus
7816250803fSAntoniu Miclaus if (i == table_size)
7826250803fSAntoniu Miclaus return -EIO;
7836250803fSAntoniu Miclaus
7846250803fSAntoniu Miclaus ret = __ad4851_get_scale(indio_dev, scale_table[i].scale_val, val,
7856250803fSAntoniu Miclaus val2);
7866250803fSAntoniu Miclaus if (ret)
7876250803fSAntoniu Miclaus return ret;
7886250803fSAntoniu Miclaus
7896250803fSAntoniu Miclaus return IIO_VAL_INT_PLUS_MICRO;
7906250803fSAntoniu Miclaus }
7916250803fSAntoniu Miclaus
ad4851_read_raw(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,int * val,int * val2,long info)7926250803fSAntoniu Miclaus static int ad4851_read_raw(struct iio_dev *indio_dev,
7936250803fSAntoniu Miclaus const struct iio_chan_spec *chan,
7946250803fSAntoniu Miclaus int *val, int *val2, long info)
7956250803fSAntoniu Miclaus {
7966250803fSAntoniu Miclaus struct ad4851_state *st = iio_priv(indio_dev);
7976250803fSAntoniu Miclaus
7986250803fSAntoniu Miclaus switch (info) {
7996250803fSAntoniu Miclaus case IIO_CHAN_INFO_SAMP_FREQ:
8006250803fSAntoniu Miclaus *val = st->cnv_trigger_rate_hz;
8016250803fSAntoniu Miclaus *val2 = st->osr;
8026250803fSAntoniu Miclaus return IIO_VAL_FRACTIONAL;
8036250803fSAntoniu Miclaus case IIO_CHAN_INFO_CALIBSCALE:
8046250803fSAntoniu Miclaus return ad4851_get_calibscale(st, chan->channel, val, val2);
8056250803fSAntoniu Miclaus case IIO_CHAN_INFO_SCALE:
8066250803fSAntoniu Miclaus return ad4851_get_scale(indio_dev, chan, val, val2);
8076250803fSAntoniu Miclaus case IIO_CHAN_INFO_CALIBBIAS:
8086250803fSAntoniu Miclaus return ad4851_get_calibbias(st, chan->channel, val);
8096250803fSAntoniu Miclaus case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
8106250803fSAntoniu Miclaus return ad4851_get_oversampling_ratio(st, val);
8116250803fSAntoniu Miclaus default:
8126250803fSAntoniu Miclaus return -EINVAL;
8136250803fSAntoniu Miclaus }
8146250803fSAntoniu Miclaus }
8156250803fSAntoniu Miclaus
ad4851_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int val,int val2,long info)8166250803fSAntoniu Miclaus static int ad4851_write_raw(struct iio_dev *indio_dev,
8176250803fSAntoniu Miclaus struct iio_chan_spec const *chan,
8186250803fSAntoniu Miclaus int val, int val2, long info)
8196250803fSAntoniu Miclaus {
8206250803fSAntoniu Miclaus struct ad4851_state *st = iio_priv(indio_dev);
8216250803fSAntoniu Miclaus
8226250803fSAntoniu Miclaus switch (info) {
8236250803fSAntoniu Miclaus case IIO_CHAN_INFO_SAMP_FREQ:
8246250803fSAntoniu Miclaus if (val < 0 || val2 < 0)
8256250803fSAntoniu Miclaus return -EINVAL;
8266250803fSAntoniu Miclaus return ad4851_set_sampling_freq(st, val * st->osr + val2 * st->osr / MICRO);
8276250803fSAntoniu Miclaus case IIO_CHAN_INFO_SCALE:
8286250803fSAntoniu Miclaus return ad4851_set_scale(indio_dev, chan, val, val2);
8296250803fSAntoniu Miclaus case IIO_CHAN_INFO_CALIBSCALE:
8306250803fSAntoniu Miclaus return ad4851_set_calibscale(st, chan->channel, val, val2);
8316250803fSAntoniu Miclaus case IIO_CHAN_INFO_CALIBBIAS:
8326250803fSAntoniu Miclaus return ad4851_set_calibbias(st, chan->channel, val);
8336250803fSAntoniu Miclaus case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
8346250803fSAntoniu Miclaus return ad4851_set_oversampling_ratio(indio_dev, chan, val);
8356250803fSAntoniu Miclaus default:
8366250803fSAntoniu Miclaus return -EINVAL;
8376250803fSAntoniu Miclaus }
8386250803fSAntoniu Miclaus }
8396250803fSAntoniu Miclaus
ad4851_update_scan_mode(struct iio_dev * indio_dev,const unsigned long * scan_mask)8406250803fSAntoniu Miclaus static int ad4851_update_scan_mode(struct iio_dev *indio_dev,
8416250803fSAntoniu Miclaus const unsigned long *scan_mask)
8426250803fSAntoniu Miclaus {
8436250803fSAntoniu Miclaus struct ad4851_state *st = iio_priv(indio_dev);
8446250803fSAntoniu Miclaus unsigned int c;
8456250803fSAntoniu Miclaus int ret;
8466250803fSAntoniu Miclaus
8476250803fSAntoniu Miclaus for (c = 0; c < indio_dev->num_channels; c++) {
8486250803fSAntoniu Miclaus if (test_bit(c, scan_mask))
8496250803fSAntoniu Miclaus ret = iio_backend_chan_enable(st->back, c);
8506250803fSAntoniu Miclaus else
8516250803fSAntoniu Miclaus ret = iio_backend_chan_disable(st->back, c);
8526250803fSAntoniu Miclaus if (ret)
8536250803fSAntoniu Miclaus return ret;
8546250803fSAntoniu Miclaus }
8556250803fSAntoniu Miclaus
8566250803fSAntoniu Miclaus return 0;
8576250803fSAntoniu Miclaus }
8586250803fSAntoniu Miclaus
ad4851_read_avail(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,const int ** vals,int * type,int * length,long mask)8596250803fSAntoniu Miclaus static int ad4851_read_avail(struct iio_dev *indio_dev,
8606250803fSAntoniu Miclaus struct iio_chan_spec const *chan,
8616250803fSAntoniu Miclaus const int **vals, int *type, int *length,
8626250803fSAntoniu Miclaus long mask)
8636250803fSAntoniu Miclaus {
8646250803fSAntoniu Miclaus struct ad4851_state *st = iio_priv(indio_dev);
8656250803fSAntoniu Miclaus
8666250803fSAntoniu Miclaus switch (mask) {
8676250803fSAntoniu Miclaus case IIO_CHAN_INFO_SCALE:
8686250803fSAntoniu Miclaus if (st->bipolar_ch[chan->channel]) {
8696250803fSAntoniu Miclaus *vals = (const int *)st->scales_bipolar;
8706250803fSAntoniu Miclaus *type = IIO_VAL_INT_PLUS_MICRO;
8716250803fSAntoniu Miclaus /* Values are stored in a 2D matrix */
8726250803fSAntoniu Miclaus *length = ARRAY_SIZE(ad4851_scale_avail_bipolar) * 2;
8736250803fSAntoniu Miclaus } else {
8746250803fSAntoniu Miclaus *vals = (const int *)st->scales_unipolar;
8756250803fSAntoniu Miclaus *type = IIO_VAL_INT_PLUS_MICRO;
8766250803fSAntoniu Miclaus /* Values are stored in a 2D matrix */
8776250803fSAntoniu Miclaus *length = ARRAY_SIZE(ad4851_scale_avail_unipolar) * 2;
8786250803fSAntoniu Miclaus }
8796250803fSAntoniu Miclaus return IIO_AVAIL_LIST;
8806250803fSAntoniu Miclaus case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
8816250803fSAntoniu Miclaus *vals = ad4851_oversampling_ratios;
8826250803fSAntoniu Miclaus *length = ARRAY_SIZE(ad4851_oversampling_ratios);
8836250803fSAntoniu Miclaus *type = IIO_VAL_INT;
8846250803fSAntoniu Miclaus return IIO_AVAIL_LIST;
8856250803fSAntoniu Miclaus default:
8866250803fSAntoniu Miclaus return -EINVAL;
8876250803fSAntoniu Miclaus }
8886250803fSAntoniu Miclaus }
8896250803fSAntoniu Miclaus
8906250803fSAntoniu Miclaus static const struct iio_scan_type ad4851_scan_type_20_u[] = {
8916250803fSAntoniu Miclaus [AD4851_SCAN_TYPE_NORMAL] = {
8926250803fSAntoniu Miclaus .sign = 'u',
8936250803fSAntoniu Miclaus .realbits = 20,
8946250803fSAntoniu Miclaus .storagebits = 32,
8956250803fSAntoniu Miclaus },
8966250803fSAntoniu Miclaus [AD4851_SCAN_TYPE_RESOLUTION_BOOST] = {
8976250803fSAntoniu Miclaus .sign = 'u',
8986250803fSAntoniu Miclaus .realbits = 24,
8996250803fSAntoniu Miclaus .storagebits = 32,
9006250803fSAntoniu Miclaus },
9016250803fSAntoniu Miclaus };
9026250803fSAntoniu Miclaus
9036250803fSAntoniu Miclaus static const struct iio_scan_type ad4851_scan_type_20_b[] = {
9046250803fSAntoniu Miclaus [AD4851_SCAN_TYPE_NORMAL] = {
9056250803fSAntoniu Miclaus .sign = 's',
9066250803fSAntoniu Miclaus .realbits = 20,
9076250803fSAntoniu Miclaus .storagebits = 32,
9086250803fSAntoniu Miclaus },
9096250803fSAntoniu Miclaus [AD4851_SCAN_TYPE_RESOLUTION_BOOST] = {
9106250803fSAntoniu Miclaus .sign = 's',
9116250803fSAntoniu Miclaus .realbits = 24,
9126250803fSAntoniu Miclaus .storagebits = 32,
9136250803fSAntoniu Miclaus },
9146250803fSAntoniu Miclaus };
9156250803fSAntoniu Miclaus
ad4851_get_current_scan_type(const struct iio_dev * indio_dev,const struct iio_chan_spec * chan)9166250803fSAntoniu Miclaus static int ad4851_get_current_scan_type(const struct iio_dev *indio_dev,
9176250803fSAntoniu Miclaus const struct iio_chan_spec *chan)
9186250803fSAntoniu Miclaus {
9196250803fSAntoniu Miclaus struct ad4851_state *st = iio_priv(indio_dev);
9206250803fSAntoniu Miclaus
9216250803fSAntoniu Miclaus return st->resolution_boost_enabled ? AD4851_SCAN_TYPE_RESOLUTION_BOOST
9226250803fSAntoniu Miclaus : AD4851_SCAN_TYPE_NORMAL;
9236250803fSAntoniu Miclaus }
9246250803fSAntoniu Miclaus
9256250803fSAntoniu Miclaus #define AD4851_IIO_CHANNEL \
9266250803fSAntoniu Miclaus .type = IIO_VOLTAGE, \
9276250803fSAntoniu Miclaus .info_mask_separate = BIT(IIO_CHAN_INFO_CALIBSCALE) | \
9286250803fSAntoniu Miclaus BIT(IIO_CHAN_INFO_CALIBBIAS) | \
9296250803fSAntoniu Miclaus BIT(IIO_CHAN_INFO_SCALE), \
9306250803fSAntoniu Miclaus .info_mask_separate_available = BIT(IIO_CHAN_INFO_SCALE), \
9316250803fSAntoniu Miclaus .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
9326250803fSAntoniu Miclaus BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
9336250803fSAntoniu Miclaus .info_mask_shared_by_all_available = \
9346250803fSAntoniu Miclaus BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
9356250803fSAntoniu Miclaus .indexed = 1
9366250803fSAntoniu Miclaus
9376250803fSAntoniu Miclaus /*
9386250803fSAntoniu Miclaus * In case of AD4858_IIO_CHANNEL the scan_type is handled dynamically during the
9396250803fSAntoniu Miclaus * parse_channels function.
9406250803fSAntoniu Miclaus */
9416250803fSAntoniu Miclaus #define AD4858_IIO_CHANNEL \
9426250803fSAntoniu Miclaus { \
9436250803fSAntoniu Miclaus AD4851_IIO_CHANNEL \
9446250803fSAntoniu Miclaus }
9456250803fSAntoniu Miclaus
9466250803fSAntoniu Miclaus #define AD4857_IIO_CHANNEL \
9476250803fSAntoniu Miclaus { \
9486250803fSAntoniu Miclaus AD4851_IIO_CHANNEL, \
9496250803fSAntoniu Miclaus .scan_type = { \
9506250803fSAntoniu Miclaus .sign = 'u', \
9516250803fSAntoniu Miclaus .realbits = 16, \
9526250803fSAntoniu Miclaus .storagebits = 16, \
9536250803fSAntoniu Miclaus }, \
9546250803fSAntoniu Miclaus }
9556250803fSAntoniu Miclaus
ad4851_parse_channels_common(struct iio_dev * indio_dev,struct iio_chan_spec ** chans,const struct iio_chan_spec ad4851_chan)9566250803fSAntoniu Miclaus static int ad4851_parse_channels_common(struct iio_dev *indio_dev,
9576250803fSAntoniu Miclaus struct iio_chan_spec **chans,
9586250803fSAntoniu Miclaus const struct iio_chan_spec ad4851_chan)
9596250803fSAntoniu Miclaus {
9606250803fSAntoniu Miclaus struct ad4851_state *st = iio_priv(indio_dev);
9616250803fSAntoniu Miclaus struct device *dev = &st->spi->dev;
9626250803fSAntoniu Miclaus struct iio_chan_spec *channels, *chan_start;
9636250803fSAntoniu Miclaus unsigned int num_channels, reg;
9646250803fSAntoniu Miclaus unsigned int index = 0;
9656250803fSAntoniu Miclaus int ret;
9666250803fSAntoniu Miclaus
9676250803fSAntoniu Miclaus num_channels = device_get_child_node_count(dev);
9686250803fSAntoniu Miclaus if (num_channels > AD4851_MAX_CH_NR)
9696250803fSAntoniu Miclaus return dev_err_probe(dev, -EINVAL, "Too many channels: %u\n",
9706250803fSAntoniu Miclaus num_channels);
9716250803fSAntoniu Miclaus
9726250803fSAntoniu Miclaus channels = devm_kcalloc(dev, num_channels, sizeof(*channels), GFP_KERNEL);
9736250803fSAntoniu Miclaus if (!channels)
9746250803fSAntoniu Miclaus return -ENOMEM;
9756250803fSAntoniu Miclaus
9766250803fSAntoniu Miclaus chan_start = channels;
9776250803fSAntoniu Miclaus
9786250803fSAntoniu Miclaus device_for_each_child_node_scoped(dev, child) {
9796250803fSAntoniu Miclaus ret = fwnode_property_read_u32(child, "reg", ®);
9806250803fSAntoniu Miclaus if (ret)
9816250803fSAntoniu Miclaus return dev_err_probe(dev, ret,
9826250803fSAntoniu Miclaus "Missing channel number\n");
9836250803fSAntoniu Miclaus if (reg >= AD4851_MAX_CH_NR)
9846250803fSAntoniu Miclaus return dev_err_probe(dev, -EINVAL,
9856250803fSAntoniu Miclaus "Invalid channel number\n");
9866250803fSAntoniu Miclaus *channels = ad4851_chan;
9876250803fSAntoniu Miclaus channels->scan_index = index++;
9886250803fSAntoniu Miclaus channels->channel = reg;
9896250803fSAntoniu Miclaus
9906250803fSAntoniu Miclaus if (fwnode_property_present(child, "diff-channels")) {
9916250803fSAntoniu Miclaus channels->channel2 = reg + st->info->max_channels;
9926250803fSAntoniu Miclaus channels->differential = 1;
9936250803fSAntoniu Miclaus }
9946250803fSAntoniu Miclaus
9956250803fSAntoniu Miclaus st->bipolar_ch[reg] = fwnode_property_read_bool(child, "bipolar");
9966250803fSAntoniu Miclaus
9976250803fSAntoniu Miclaus if (st->bipolar_ch[reg]) {
9986250803fSAntoniu Miclaus channels->scan_type.sign = 's';
9996250803fSAntoniu Miclaus } else {
10006250803fSAntoniu Miclaus ret = regmap_write(st->regmap, AD4851_REG_CHX_SOFTSPAN(reg),
10016250803fSAntoniu Miclaus AD4851_SOFTSPAN_0V_40V);
10026250803fSAntoniu Miclaus if (ret)
10036250803fSAntoniu Miclaus return ret;
10046250803fSAntoniu Miclaus }
10056250803fSAntoniu Miclaus
10066250803fSAntoniu Miclaus channels++;
10076250803fSAntoniu Miclaus }
10086250803fSAntoniu Miclaus
10096250803fSAntoniu Miclaus *chans = chan_start;
10106250803fSAntoniu Miclaus
10116250803fSAntoniu Miclaus return num_channels;
10126250803fSAntoniu Miclaus }
10136250803fSAntoniu Miclaus
ad4857_parse_channels(struct iio_dev * indio_dev)10146250803fSAntoniu Miclaus static int ad4857_parse_channels(struct iio_dev *indio_dev)
10156250803fSAntoniu Miclaus {
10166250803fSAntoniu Miclaus struct iio_chan_spec *ad4851_channels;
10176250803fSAntoniu Miclaus const struct iio_chan_spec ad4851_chan = AD4857_IIO_CHANNEL;
10186250803fSAntoniu Miclaus int ret;
10196250803fSAntoniu Miclaus
10206250803fSAntoniu Miclaus ret = ad4851_parse_channels_common(indio_dev, &ad4851_channels,
10216250803fSAntoniu Miclaus ad4851_chan);
10226250803fSAntoniu Miclaus if (ret < 0)
10236250803fSAntoniu Miclaus return ret;
10246250803fSAntoniu Miclaus
10256250803fSAntoniu Miclaus indio_dev->channels = ad4851_channels;
10266250803fSAntoniu Miclaus indio_dev->num_channels = ret;
10276250803fSAntoniu Miclaus
10286250803fSAntoniu Miclaus return 0;
10296250803fSAntoniu Miclaus }
10306250803fSAntoniu Miclaus
ad4858_parse_channels(struct iio_dev * indio_dev)10316250803fSAntoniu Miclaus static int ad4858_parse_channels(struct iio_dev *indio_dev)
10326250803fSAntoniu Miclaus {
10336250803fSAntoniu Miclaus struct ad4851_state *st = iio_priv(indio_dev);
10346250803fSAntoniu Miclaus struct device *dev = &st->spi->dev;
10356250803fSAntoniu Miclaus struct iio_chan_spec *ad4851_channels;
10366250803fSAntoniu Miclaus const struct iio_chan_spec ad4851_chan = AD4858_IIO_CHANNEL;
1037*499a8ceeSAntoniu Miclaus int ret, i = 0;
10386250803fSAntoniu Miclaus
10396250803fSAntoniu Miclaus ret = ad4851_parse_channels_common(indio_dev, &ad4851_channels,
10406250803fSAntoniu Miclaus ad4851_chan);
10416250803fSAntoniu Miclaus if (ret < 0)
10426250803fSAntoniu Miclaus return ret;
10436250803fSAntoniu Miclaus
10446250803fSAntoniu Miclaus device_for_each_child_node_scoped(dev, child) {
1045*499a8ceeSAntoniu Miclaus ad4851_channels[i].has_ext_scan_type = 1;
10466250803fSAntoniu Miclaus if (fwnode_property_read_bool(child, "bipolar")) {
1047*499a8ceeSAntoniu Miclaus ad4851_channels[i].ext_scan_type = ad4851_scan_type_20_b;
1048*499a8ceeSAntoniu Miclaus ad4851_channels[i].num_ext_scan_type = ARRAY_SIZE(ad4851_scan_type_20_b);
10496250803fSAntoniu Miclaus } else {
1050*499a8ceeSAntoniu Miclaus ad4851_channels[i].ext_scan_type = ad4851_scan_type_20_u;
1051*499a8ceeSAntoniu Miclaus ad4851_channels[i].num_ext_scan_type = ARRAY_SIZE(ad4851_scan_type_20_u);
10526250803fSAntoniu Miclaus }
1053*499a8ceeSAntoniu Miclaus i++;
10546250803fSAntoniu Miclaus }
10556250803fSAntoniu Miclaus
10566250803fSAntoniu Miclaus indio_dev->channels = ad4851_channels;
10576250803fSAntoniu Miclaus indio_dev->num_channels = ret;
10586250803fSAntoniu Miclaus
10596250803fSAntoniu Miclaus return 0;
10606250803fSAntoniu Miclaus }
10616250803fSAntoniu Miclaus
10626250803fSAntoniu Miclaus /*
10636250803fSAntoniu Miclaus * parse_channels() function handles the rest of the channel related attributes
10646250803fSAntoniu Miclaus * that are usually are stored in the chip info structure.
10656250803fSAntoniu Miclaus */
10666250803fSAntoniu Miclaus static const struct ad4851_chip_info ad4851_info = {
10676250803fSAntoniu Miclaus .name = "ad4851",
10686250803fSAntoniu Miclaus .product_id = 0x67,
10696250803fSAntoniu Miclaus .max_sample_rate_hz = 250 * KILO,
10706250803fSAntoniu Miclaus .resolution = 16,
10716250803fSAntoniu Miclaus .max_channels = AD4851_MAX_CH_NR,
10726250803fSAntoniu Miclaus .parse_channels = ad4857_parse_channels,
10736250803fSAntoniu Miclaus };
10746250803fSAntoniu Miclaus
10756250803fSAntoniu Miclaus static const struct ad4851_chip_info ad4852_info = {
10766250803fSAntoniu Miclaus .name = "ad4852",
10776250803fSAntoniu Miclaus .product_id = 0x66,
10786250803fSAntoniu Miclaus .max_sample_rate_hz = 250 * KILO,
10796250803fSAntoniu Miclaus .resolution = 20,
10806250803fSAntoniu Miclaus .max_channels = AD4851_MAX_CH_NR,
10816250803fSAntoniu Miclaus .parse_channels = ad4858_parse_channels,
10826250803fSAntoniu Miclaus };
10836250803fSAntoniu Miclaus
10846250803fSAntoniu Miclaus static const struct ad4851_chip_info ad4853_info = {
10856250803fSAntoniu Miclaus .name = "ad4853",
10866250803fSAntoniu Miclaus .product_id = 0x65,
10876250803fSAntoniu Miclaus .max_sample_rate_hz = 1 * MEGA,
10886250803fSAntoniu Miclaus .resolution = 16,
10896250803fSAntoniu Miclaus .max_channels = AD4851_MAX_CH_NR,
10906250803fSAntoniu Miclaus .parse_channels = ad4857_parse_channels,
10916250803fSAntoniu Miclaus };
10926250803fSAntoniu Miclaus
10936250803fSAntoniu Miclaus static const struct ad4851_chip_info ad4854_info = {
10946250803fSAntoniu Miclaus .name = "ad4854",
10956250803fSAntoniu Miclaus .product_id = 0x64,
10966250803fSAntoniu Miclaus .max_sample_rate_hz = 1 * MEGA,
10976250803fSAntoniu Miclaus .resolution = 20,
10986250803fSAntoniu Miclaus .max_channels = AD4851_MAX_CH_NR,
10996250803fSAntoniu Miclaus .parse_channels = ad4858_parse_channels,
11006250803fSAntoniu Miclaus };
11016250803fSAntoniu Miclaus
11026250803fSAntoniu Miclaus static const struct ad4851_chip_info ad4855_info = {
11036250803fSAntoniu Miclaus .name = "ad4855",
11046250803fSAntoniu Miclaus .product_id = 0x63,
11056250803fSAntoniu Miclaus .max_sample_rate_hz = 250 * KILO,
11066250803fSAntoniu Miclaus .resolution = 16,
11076250803fSAntoniu Miclaus .max_channels = AD4851_MAX_CH_NR,
11086250803fSAntoniu Miclaus .parse_channels = ad4857_parse_channels,
11096250803fSAntoniu Miclaus };
11106250803fSAntoniu Miclaus
11116250803fSAntoniu Miclaus static const struct ad4851_chip_info ad4856_info = {
11126250803fSAntoniu Miclaus .name = "ad4856",
11136250803fSAntoniu Miclaus .product_id = 0x62,
11146250803fSAntoniu Miclaus .max_sample_rate_hz = 250 * KILO,
11156250803fSAntoniu Miclaus .resolution = 20,
11166250803fSAntoniu Miclaus .max_channels = AD4851_MAX_CH_NR,
11176250803fSAntoniu Miclaus .parse_channels = ad4858_parse_channels,
11186250803fSAntoniu Miclaus };
11196250803fSAntoniu Miclaus
11206250803fSAntoniu Miclaus static const struct ad4851_chip_info ad4857_info = {
11216250803fSAntoniu Miclaus .name = "ad4857",
11226250803fSAntoniu Miclaus .product_id = 0x61,
11236250803fSAntoniu Miclaus .max_sample_rate_hz = 1 * MEGA,
11246250803fSAntoniu Miclaus .resolution = 16,
11256250803fSAntoniu Miclaus .max_channels = AD4851_MAX_CH_NR,
11266250803fSAntoniu Miclaus .parse_channels = ad4857_parse_channels,
11276250803fSAntoniu Miclaus };
11286250803fSAntoniu Miclaus
11296250803fSAntoniu Miclaus static const struct ad4851_chip_info ad4858_info = {
11306250803fSAntoniu Miclaus .name = "ad4858",
11316250803fSAntoniu Miclaus .product_id = 0x60,
11326250803fSAntoniu Miclaus .max_sample_rate_hz = 1 * MEGA,
11336250803fSAntoniu Miclaus .resolution = 20,
11346250803fSAntoniu Miclaus .max_channels = AD4851_MAX_CH_NR,
11356250803fSAntoniu Miclaus .parse_channels = ad4858_parse_channels,
11366250803fSAntoniu Miclaus };
11376250803fSAntoniu Miclaus
11386250803fSAntoniu Miclaus static const struct ad4851_chip_info ad4858i_info = {
11396250803fSAntoniu Miclaus .name = "ad4858i",
11406250803fSAntoniu Miclaus .product_id = 0x6F,
11416250803fSAntoniu Miclaus .max_sample_rate_hz = 1 * MEGA,
11426250803fSAntoniu Miclaus .resolution = 20,
11436250803fSAntoniu Miclaus .max_channels = AD4851_MAX_CH_NR,
11446250803fSAntoniu Miclaus .parse_channels = ad4858_parse_channels,
11456250803fSAntoniu Miclaus };
11466250803fSAntoniu Miclaus
11476250803fSAntoniu Miclaus static const struct iio_info ad4851_iio_info = {
11486250803fSAntoniu Miclaus .debugfs_reg_access = ad4851_reg_access,
11496250803fSAntoniu Miclaus .read_raw = ad4851_read_raw,
11506250803fSAntoniu Miclaus .write_raw = ad4851_write_raw,
11516250803fSAntoniu Miclaus .update_scan_mode = ad4851_update_scan_mode,
11526250803fSAntoniu Miclaus .get_current_scan_type = ad4851_get_current_scan_type,
11536250803fSAntoniu Miclaus .read_avail = ad4851_read_avail,
11546250803fSAntoniu Miclaus };
11556250803fSAntoniu Miclaus
11566250803fSAntoniu Miclaus static const struct regmap_config regmap_config = {
11576250803fSAntoniu Miclaus .reg_bits = 16,
11586250803fSAntoniu Miclaus .val_bits = 8,
11596250803fSAntoniu Miclaus .read_flag_mask = BIT(7),
11606250803fSAntoniu Miclaus };
11616250803fSAntoniu Miclaus
11626250803fSAntoniu Miclaus static const char * const ad4851_power_supplies[] = {
11636250803fSAntoniu Miclaus "vcc", "vdd", "vee", "vio",
11646250803fSAntoniu Miclaus };
11656250803fSAntoniu Miclaus
ad4851_probe(struct spi_device * spi)11666250803fSAntoniu Miclaus static int ad4851_probe(struct spi_device *spi)
11676250803fSAntoniu Miclaus {
11686250803fSAntoniu Miclaus struct iio_dev *indio_dev;
11696250803fSAntoniu Miclaus struct device *dev = &spi->dev;
11706250803fSAntoniu Miclaus struct ad4851_state *st;
11716250803fSAntoniu Miclaus int ret;
11726250803fSAntoniu Miclaus
11736250803fSAntoniu Miclaus indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
11746250803fSAntoniu Miclaus if (!indio_dev)
11756250803fSAntoniu Miclaus return -ENOMEM;
11766250803fSAntoniu Miclaus
11776250803fSAntoniu Miclaus st = iio_priv(indio_dev);
11786250803fSAntoniu Miclaus st->spi = spi;
11796250803fSAntoniu Miclaus
11806250803fSAntoniu Miclaus ret = devm_mutex_init(dev, &st->lock);
11816250803fSAntoniu Miclaus if (ret)
11826250803fSAntoniu Miclaus return ret;
11836250803fSAntoniu Miclaus
11846250803fSAntoniu Miclaus ret = devm_regulator_bulk_get_enable(dev,
11856250803fSAntoniu Miclaus ARRAY_SIZE(ad4851_power_supplies),
11866250803fSAntoniu Miclaus ad4851_power_supplies);
11876250803fSAntoniu Miclaus if (ret)
11886250803fSAntoniu Miclaus return dev_err_probe(dev, ret,
11896250803fSAntoniu Miclaus "failed to get and enable supplies\n");
11906250803fSAntoniu Miclaus
11916250803fSAntoniu Miclaus ret = devm_regulator_get_enable_optional(dev, "vddh");
11926250803fSAntoniu Miclaus if (ret < 0 && ret != -ENODEV)
11936250803fSAntoniu Miclaus return dev_err_probe(dev, ret, "failed to enable vddh voltage\n");
11946250803fSAntoniu Miclaus
11956250803fSAntoniu Miclaus ret = devm_regulator_get_enable_optional(dev, "vddl");
11966250803fSAntoniu Miclaus if (ret < 0 && ret != -ENODEV)
11976250803fSAntoniu Miclaus return dev_err_probe(dev, ret, "failed to enable vddl voltage\n");
11986250803fSAntoniu Miclaus
11996250803fSAntoniu Miclaus ret = devm_regulator_get_enable_optional(dev, "vrefbuf");
12006250803fSAntoniu Miclaus if (ret < 0 && ret != -ENODEV)
12016250803fSAntoniu Miclaus return dev_err_probe(dev, ret, "failed to enable vrefbuf voltage\n");
12026250803fSAntoniu Miclaus
12036250803fSAntoniu Miclaus st->vrefbuf_en = ret != -ENODEV;
12046250803fSAntoniu Miclaus
12056250803fSAntoniu Miclaus ret = devm_regulator_get_enable_optional(dev, "vrefio");
12066250803fSAntoniu Miclaus if (ret < 0 && ret != -ENODEV)
12076250803fSAntoniu Miclaus return dev_err_probe(dev, ret, "failed to enable vrefio voltage\n");
12086250803fSAntoniu Miclaus
12096250803fSAntoniu Miclaus st->vrefio_en = ret != -ENODEV;
12106250803fSAntoniu Miclaus
12116250803fSAntoniu Miclaus st->pd_gpio = devm_gpiod_get_optional(dev, "pd", GPIOD_OUT_LOW);
12126250803fSAntoniu Miclaus if (IS_ERR(st->pd_gpio))
12136250803fSAntoniu Miclaus return dev_err_probe(dev, PTR_ERR(st->pd_gpio),
12146250803fSAntoniu Miclaus "Error on requesting pd GPIO\n");
12156250803fSAntoniu Miclaus
12166250803fSAntoniu Miclaus st->cnv = devm_pwm_get(dev, NULL);
12176250803fSAntoniu Miclaus if (IS_ERR(st->cnv))
12186250803fSAntoniu Miclaus return dev_err_probe(dev, PTR_ERR(st->cnv),
12196250803fSAntoniu Miclaus "Error on requesting pwm\n");
12206250803fSAntoniu Miclaus
12216250803fSAntoniu Miclaus st->info = spi_get_device_match_data(spi);
12226250803fSAntoniu Miclaus if (!st->info)
12236250803fSAntoniu Miclaus return -ENODEV;
12246250803fSAntoniu Miclaus
12256250803fSAntoniu Miclaus st->regmap = devm_regmap_init_spi(spi, ®map_config);
12266250803fSAntoniu Miclaus if (IS_ERR(st->regmap))
12276250803fSAntoniu Miclaus return PTR_ERR(st->regmap);
12286250803fSAntoniu Miclaus
12296250803fSAntoniu Miclaus ret = ad4851_set_sampling_freq(st, HZ_PER_MHZ);
12306250803fSAntoniu Miclaus if (ret)
12316250803fSAntoniu Miclaus return ret;
12326250803fSAntoniu Miclaus
12336250803fSAntoniu Miclaus ret = devm_add_action_or_reset(&st->spi->dev, ad4851_pwm_disable,
12346250803fSAntoniu Miclaus st->cnv);
12356250803fSAntoniu Miclaus if (ret)
12366250803fSAntoniu Miclaus return ret;
12376250803fSAntoniu Miclaus
12386250803fSAntoniu Miclaus ret = ad4851_setup(st);
12396250803fSAntoniu Miclaus if (ret)
12406250803fSAntoniu Miclaus return ret;
12416250803fSAntoniu Miclaus
12426250803fSAntoniu Miclaus indio_dev->name = st->info->name;
12436250803fSAntoniu Miclaus indio_dev->info = &ad4851_iio_info;
12446250803fSAntoniu Miclaus indio_dev->modes = INDIO_DIRECT_MODE;
12456250803fSAntoniu Miclaus
12466250803fSAntoniu Miclaus ret = st->info->parse_channels(indio_dev);
12476250803fSAntoniu Miclaus if (ret)
12486250803fSAntoniu Miclaus return ret;
12496250803fSAntoniu Miclaus
12506250803fSAntoniu Miclaus ret = ad4851_scale_fill(indio_dev);
12516250803fSAntoniu Miclaus if (ret)
12526250803fSAntoniu Miclaus return ret;
12536250803fSAntoniu Miclaus
12546250803fSAntoniu Miclaus st->back = devm_iio_backend_get(dev, NULL);
12556250803fSAntoniu Miclaus if (IS_ERR(st->back))
12566250803fSAntoniu Miclaus return PTR_ERR(st->back);
12576250803fSAntoniu Miclaus
12586250803fSAntoniu Miclaus ret = devm_iio_backend_request_buffer(dev, st->back, indio_dev);
12596250803fSAntoniu Miclaus if (ret)
12606250803fSAntoniu Miclaus return ret;
12616250803fSAntoniu Miclaus
12626250803fSAntoniu Miclaus ret = devm_iio_backend_enable(dev, st->back);
12636250803fSAntoniu Miclaus if (ret)
12646250803fSAntoniu Miclaus return ret;
12656250803fSAntoniu Miclaus
12666250803fSAntoniu Miclaus ret = ad4851_calibrate(indio_dev);
12676250803fSAntoniu Miclaus if (ret)
12686250803fSAntoniu Miclaus return ret;
12696250803fSAntoniu Miclaus
12706250803fSAntoniu Miclaus return devm_iio_device_register(dev, indio_dev);
12716250803fSAntoniu Miclaus }
12726250803fSAntoniu Miclaus
12736250803fSAntoniu Miclaus static const struct of_device_id ad4851_of_match[] = {
12746250803fSAntoniu Miclaus { .compatible = "adi,ad4851", .data = &ad4851_info, },
12756250803fSAntoniu Miclaus { .compatible = "adi,ad4852", .data = &ad4852_info, },
12766250803fSAntoniu Miclaus { .compatible = "adi,ad4853", .data = &ad4853_info, },
12776250803fSAntoniu Miclaus { .compatible = "adi,ad4854", .data = &ad4854_info, },
12786250803fSAntoniu Miclaus { .compatible = "adi,ad4855", .data = &ad4855_info, },
12796250803fSAntoniu Miclaus { .compatible = "adi,ad4856", .data = &ad4856_info, },
12806250803fSAntoniu Miclaus { .compatible = "adi,ad4857", .data = &ad4857_info, },
12816250803fSAntoniu Miclaus { .compatible = "adi,ad4858", .data = &ad4858_info, },
12826250803fSAntoniu Miclaus { .compatible = "adi,ad4858i", .data = &ad4858i_info, },
12836250803fSAntoniu Miclaus { }
12846250803fSAntoniu Miclaus };
12856250803fSAntoniu Miclaus
12866250803fSAntoniu Miclaus static const struct spi_device_id ad4851_spi_id[] = {
12876250803fSAntoniu Miclaus { "ad4851", (kernel_ulong_t)&ad4851_info },
12886250803fSAntoniu Miclaus { "ad4852", (kernel_ulong_t)&ad4852_info },
12896250803fSAntoniu Miclaus { "ad4853", (kernel_ulong_t)&ad4853_info },
12906250803fSAntoniu Miclaus { "ad4854", (kernel_ulong_t)&ad4854_info },
12916250803fSAntoniu Miclaus { "ad4855", (kernel_ulong_t)&ad4855_info },
12926250803fSAntoniu Miclaus { "ad4856", (kernel_ulong_t)&ad4856_info },
12936250803fSAntoniu Miclaus { "ad4857", (kernel_ulong_t)&ad4857_info },
12946250803fSAntoniu Miclaus { "ad4858", (kernel_ulong_t)&ad4858_info },
12956250803fSAntoniu Miclaus { "ad4858i", (kernel_ulong_t)&ad4858i_info },
12966250803fSAntoniu Miclaus { }
12976250803fSAntoniu Miclaus };
12986250803fSAntoniu Miclaus MODULE_DEVICE_TABLE(spi, ad4851_spi_id);
12996250803fSAntoniu Miclaus
13006250803fSAntoniu Miclaus static struct spi_driver ad4851_driver = {
13016250803fSAntoniu Miclaus .probe = ad4851_probe,
13026250803fSAntoniu Miclaus .driver = {
13036250803fSAntoniu Miclaus .name = "ad4851",
13046250803fSAntoniu Miclaus .of_match_table = ad4851_of_match,
13056250803fSAntoniu Miclaus },
13066250803fSAntoniu Miclaus .id_table = ad4851_spi_id,
13076250803fSAntoniu Miclaus };
13086250803fSAntoniu Miclaus module_spi_driver(ad4851_driver);
13096250803fSAntoniu Miclaus
13106250803fSAntoniu Miclaus MODULE_AUTHOR("Sergiu Cuciurean <sergiu.cuciurean@analog.com>");
13116250803fSAntoniu Miclaus MODULE_AUTHOR("Dragos Bogdan <dragos.bogdan@analog.com>");
13126250803fSAntoniu Miclaus MODULE_AUTHOR("Antoniu Miclaus <antoniu.miclaus@analog.com>");
13136250803fSAntoniu Miclaus MODULE_DESCRIPTION("Analog Devices AD4851 DAS driver");
13146250803fSAntoniu Miclaus MODULE_LICENSE("GPL");
13156250803fSAntoniu Miclaus MODULE_IMPORT_NS("IIO_BACKEND");
1316