Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * ADA4250 driver
0004  *
0005  * Copyright 2022 Analog Devices Inc.
0006  */
0007 
0008 #include <linux/bitfield.h>
0009 #include <linux/bits.h>
0010 #include <linux/device.h>
0011 #include <linux/iio/iio.h>
0012 #include <linux/module.h>
0013 #include <linux/regmap.h>
0014 #include <linux/regulator/consumer.h>
0015 #include <linux/spi/spi.h>
0016 
0017 #include <asm/unaligned.h>
0018 
0019 /* ADA4250 Register Map */
0020 #define ADA4250_REG_GAIN_MUX        0x00
0021 #define ADA4250_REG_REFBUF_EN       0x01
0022 #define ADA4250_REG_RESET           0x02
0023 #define ADA4250_REG_SNSR_CAL_VAL    0x04
0024 #define ADA4250_REG_SNSR_CAL_CNFG   0x05
0025 #define ADA4250_REG_DIE_REV         0x18
0026 #define ADA4250_REG_CHIP_ID         0x19
0027 
0028 /* ADA4250_REG_GAIN_MUX Map */
0029 #define ADA4250_GAIN_MUX_MSK        GENMASK(2, 0)
0030 
0031 /* ADA4250_REG_REFBUF Map */
0032 #define ADA4250_REFBUF_MSK          BIT(0)
0033 
0034 /* ADA4250_REG_RESET Map */
0035 #define ADA4250_RESET_MSK           BIT(0)
0036 
0037 /* ADA4250_REG_SNSR_CAL_VAL Map */
0038 #define ADA4250_CAL_CFG_BIAS_MSK    GENMASK(7, 0)
0039 
0040 /* ADA4250_REG_SNSR_CAL_CNFG Bit Definition */
0041 #define ADA4250_BIAS_SET_MSK        GENMASK(3, 2)
0042 #define ADA4250_RANGE_SET_MSK       GENMASK(1, 0)
0043 
0044 /* Miscellaneous definitions */
0045 #define ADA4250_CHIP_ID             0x4250
0046 #define ADA4250_RANGE1              0
0047 #define ADA4250_RANGE4              3
0048 
0049 /* ADA4250 current bias set */
0050 enum ada4250_current_bias {
0051     ADA4250_BIAS_DISABLED,
0052     ADA4250_BIAS_BANDGAP,
0053     ADA4250_BIAS_AVDD,
0054 };
0055 
0056 struct ada4250_state {
0057     struct spi_device   *spi;
0058     struct regmap       *regmap;
0059     struct regulator    *reg;
0060     /* Protect against concurrent accesses to the device and data content */
0061     struct mutex        lock;
0062     u8          bias;
0063     u8          gain;
0064     int         offset_uv;
0065     bool            refbuf_en;
0066 };
0067 
0068 /* ADA4250 Current Bias Source Settings: Disabled, Bandgap Reference, AVDD */
0069 static const int calibbias_table[] = {0, 1, 2};
0070 
0071 /* ADA4250 Gain (V/V) values: 1, 2, 4, 8, 16, 32, 64, 128 */
0072 static const int hwgain_table[] = {1, 2, 4, 8, 16, 32, 64, 128};
0073 
0074 static const struct regmap_config ada4250_regmap_config = {
0075     .reg_bits = 8,
0076     .val_bits = 8,
0077     .read_flag_mask = BIT(7),
0078     .max_register = 0x1A,
0079 };
0080 
0081 static int ada4250_set_offset_uv(struct iio_dev *indio_dev,
0082                  const struct iio_chan_spec *chan,
0083                  int offset_uv)
0084 {
0085     struct ada4250_state *st = iio_priv(indio_dev);
0086 
0087     int i, ret, x[8], max_vos, min_vos, voltage_v, vlsb = 0;
0088     u8 offset_raw, range = ADA4250_RANGE1;
0089     u32 lsb_coeff[6] = {1333, 2301, 4283, 8289, 16311, 31599};
0090 
0091     if (st->bias == 0 || st->bias == 3)
0092         return -EINVAL;
0093 
0094     voltage_v = regulator_get_voltage(st->reg);
0095     voltage_v = DIV_ROUND_CLOSEST(voltage_v, 1000000);
0096 
0097     if (st->bias == ADA4250_BIAS_AVDD)
0098         x[0] = voltage_v;
0099     else
0100         x[0] = 5;
0101 
0102     x[1] = 126 * (x[0] - 1);
0103 
0104     for (i = 0; i < 6; i++)
0105         x[i + 2] = DIV_ROUND_CLOSEST(x[1] * 1000, lsb_coeff[i]);
0106 
0107     if (st->gain == 0)
0108         return -EINVAL;
0109 
0110     /*
0111      * Compute Range and Voltage per LSB for the Sensor Offset Calibration
0112      * Example of computation for Range 1 and Range 2 (Curren Bias Set = AVDD):
0113      *                     Range 1                            Range 2
0114      *   Gain   | Max Vos(mV) |   LSB(mV)        |  Max Vos(mV)  | LSB(mV) |
0115      *    2     |    X1*127   | X1=0.126(AVDD-1) |   X1*3*127    |  X1*3   |
0116      *    4     |    X2*127   | X2=X1/1.3333     |   X2*3*127    |  X2*3   |
0117      *    8     |    X3*127   | X3=X1/2.301      |   X3*3*127    |  X3*3   |
0118      *    16    |    X4*127   | X4=X1/4.283      |   X4*3*127    |  X4*3   |
0119      *    32    |    X5*127   | X5=X1/8.289      |   X5*3*127    |  X5*3   |
0120      *    64    |    X6*127   | X6=X1/16.311     |   X6*3*127    |  X6*3   |
0121      *    128   |    X7*127   | X7=X1/31.599     |   X7*3*127    |  X7*3   |
0122      */
0123     for (i = ADA4250_RANGE1; i <= ADA4250_RANGE4; i++) {
0124         max_vos = x[st->gain] *  127 * ((1 << (i + 1)) - 1);
0125         min_vos = -1 * max_vos;
0126         if (offset_uv > min_vos && offset_uv < max_vos) {
0127             range = i;
0128             vlsb = x[st->gain] * ((1 << (i + 1)) - 1);
0129             break;
0130         }
0131     }
0132 
0133     if (vlsb <= 0)
0134         return -EINVAL;
0135 
0136     offset_raw = DIV_ROUND_CLOSEST(abs(offset_uv), vlsb);
0137 
0138     mutex_lock(&st->lock);
0139     ret = regmap_update_bits(st->regmap, ADA4250_REG_SNSR_CAL_CNFG,
0140                  ADA4250_RANGE_SET_MSK,
0141                  FIELD_PREP(ADA4250_RANGE_SET_MSK, range));
0142     if (ret)
0143         goto exit;
0144 
0145     st->offset_uv = offset_raw * vlsb;
0146 
0147     /*
0148      * To set the offset calibration value, use bits [6:0] and bit 7 as the
0149      * polarity bit (set to "0" for a negative offset and "1" for a positive
0150      * offset).
0151      */
0152     if (offset_uv < 0) {
0153         offset_raw |= BIT(7);
0154         st->offset_uv *= (-1);
0155     }
0156 
0157     ret = regmap_write(st->regmap, ADA4250_REG_SNSR_CAL_VAL, offset_raw);
0158 
0159 exit:
0160     mutex_unlock(&st->lock);
0161 
0162     return ret;
0163 }
0164 
0165 static int ada4250_read_raw(struct iio_dev *indio_dev,
0166                 struct iio_chan_spec const *chan,
0167                 int *val, int *val2, long info)
0168 {
0169     struct ada4250_state *st = iio_priv(indio_dev);
0170     int ret;
0171 
0172     switch (info) {
0173     case IIO_CHAN_INFO_HARDWAREGAIN:
0174         ret = regmap_read(st->regmap, ADA4250_REG_GAIN_MUX, val);
0175         if (ret)
0176             return ret;
0177 
0178         *val = BIT(*val);
0179 
0180         return IIO_VAL_INT;
0181     case IIO_CHAN_INFO_OFFSET:
0182         *val = st->offset_uv;
0183 
0184         return IIO_VAL_INT;
0185     case IIO_CHAN_INFO_CALIBBIAS:
0186         ret = regmap_read(st->regmap, ADA4250_REG_SNSR_CAL_CNFG, val);
0187         if (ret)
0188             return ret;
0189 
0190         *val = FIELD_GET(ADA4250_BIAS_SET_MSK, *val);
0191 
0192         return IIO_VAL_INT;
0193     case IIO_CHAN_INFO_SCALE:
0194         *val = 1;
0195         *val2 = 1000000;
0196 
0197         return IIO_VAL_FRACTIONAL;
0198     default:
0199         return -EINVAL;
0200     }
0201 }
0202 
0203 static int ada4250_write_raw(struct iio_dev *indio_dev,
0204                  struct iio_chan_spec const *chan,
0205                  int val, int val2, long info)
0206 {
0207     struct ada4250_state *st = iio_priv(indio_dev);
0208     int ret;
0209 
0210     switch (info) {
0211     case IIO_CHAN_INFO_HARDWAREGAIN:
0212         ret = regmap_write(st->regmap, ADA4250_REG_GAIN_MUX,
0213                    FIELD_PREP(ADA4250_GAIN_MUX_MSK, ilog2(val)));
0214         if (ret)
0215             return ret;
0216 
0217         st->gain = ilog2(val);
0218 
0219         return ret;
0220     case IIO_CHAN_INFO_OFFSET:
0221         return ada4250_set_offset_uv(indio_dev, chan, val);
0222     case IIO_CHAN_INFO_CALIBBIAS:
0223         ret = regmap_update_bits(st->regmap, ADA4250_REG_SNSR_CAL_CNFG,
0224                      ADA4250_BIAS_SET_MSK,
0225                      FIELD_PREP(ADA4250_BIAS_SET_MSK, val));
0226         if (ret)
0227             return ret;
0228 
0229         st->bias = val;
0230 
0231         return ret;
0232     default:
0233         return -EINVAL;
0234     }
0235 }
0236 
0237 static int ada4250_read_avail(struct iio_dev *indio_dev,
0238                   struct iio_chan_spec const *chan,
0239                   const int **vals, int *type, int *length,
0240                   long mask)
0241 {
0242     switch (mask) {
0243     case IIO_CHAN_INFO_CALIBBIAS:
0244         *vals = calibbias_table;
0245         *type = IIO_VAL_INT;
0246         *length = ARRAY_SIZE(calibbias_table);
0247 
0248         return IIO_AVAIL_LIST;
0249     case IIO_CHAN_INFO_HARDWAREGAIN:
0250         *vals = hwgain_table;
0251         *type = IIO_VAL_INT;
0252         *length = ARRAY_SIZE(hwgain_table);
0253 
0254         return IIO_AVAIL_LIST;
0255     default:
0256         return -EINVAL;
0257     }
0258 }
0259 
0260 static int ada4250_reg_access(struct iio_dev *indio_dev,
0261                   unsigned int reg,
0262                   unsigned int write_val,
0263                   unsigned int *read_val)
0264 {
0265     struct ada4250_state *st = iio_priv(indio_dev);
0266 
0267     if (read_val)
0268         return regmap_read(st->regmap, reg, read_val);
0269     else
0270         return regmap_write(st->regmap, reg, write_val);
0271 }
0272 
0273 static const struct iio_info ada4250_info = {
0274     .read_raw = ada4250_read_raw,
0275     .write_raw = ada4250_write_raw,
0276     .read_avail = &ada4250_read_avail,
0277     .debugfs_reg_access = &ada4250_reg_access,
0278 };
0279 
0280 static const struct iio_chan_spec ada4250_channels[] = {
0281     {
0282         .type = IIO_VOLTAGE,
0283         .output = 1,
0284         .indexed = 1,
0285         .channel = 0,
0286         .info_mask_separate = BIT(IIO_CHAN_INFO_HARDWAREGAIN) |
0287                 BIT(IIO_CHAN_INFO_OFFSET) |
0288                 BIT(IIO_CHAN_INFO_CALIBBIAS) |
0289                 BIT(IIO_CHAN_INFO_SCALE),
0290         .info_mask_separate_available = BIT(IIO_CHAN_INFO_CALIBBIAS) |
0291                         BIT(IIO_CHAN_INFO_HARDWAREGAIN),
0292     }
0293 };
0294 
0295 static void ada4250_reg_disable(void *data)
0296 {
0297     regulator_disable(data);
0298 }
0299 
0300 static int ada4250_init(struct ada4250_state *st)
0301 {
0302     int ret;
0303     u16 chip_id;
0304     u8 data[2] __aligned(8) = {};
0305     struct spi_device *spi = st->spi;
0306 
0307     st->refbuf_en = device_property_read_bool(&spi->dev, "adi,refbuf-enable");
0308 
0309     st->reg = devm_regulator_get(&spi->dev, "avdd");
0310     if (IS_ERR(st->reg))
0311         return dev_err_probe(&spi->dev, PTR_ERR(st->reg),
0312                      "failed to get the AVDD voltage\n");
0313 
0314     ret = regulator_enable(st->reg);
0315     if (ret) {
0316         dev_err(&spi->dev, "Failed to enable specified AVDD supply\n");
0317         return ret;
0318     }
0319 
0320     ret = devm_add_action_or_reset(&spi->dev, ada4250_reg_disable, st->reg);
0321     if (ret)
0322         return ret;
0323 
0324     ret = regmap_write(st->regmap, ADA4250_REG_RESET,
0325                FIELD_PREP(ADA4250_RESET_MSK, 1));
0326     if (ret)
0327         return ret;
0328 
0329     ret = regmap_bulk_read(st->regmap, ADA4250_REG_CHIP_ID, data, 2);
0330     if (ret)
0331         return ret;
0332 
0333     chip_id = get_unaligned_le16(data);
0334 
0335     if (chip_id != ADA4250_CHIP_ID) {
0336         dev_err(&spi->dev, "Invalid chip ID.\n");
0337         return -EINVAL;
0338     }
0339 
0340     return regmap_write(st->regmap, ADA4250_REG_REFBUF_EN,
0341                 FIELD_PREP(ADA4250_REFBUF_MSK, st->refbuf_en));
0342 }
0343 
0344 static int ada4250_probe(struct spi_device *spi)
0345 {
0346     struct iio_dev *indio_dev;
0347     struct regmap *regmap;
0348     struct ada4250_state *st;
0349     int ret;
0350 
0351     indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
0352     if (!indio_dev)
0353         return -ENOMEM;
0354 
0355     regmap = devm_regmap_init_spi(spi, &ada4250_regmap_config);
0356     if (IS_ERR(regmap))
0357         return PTR_ERR(regmap);
0358 
0359     st = iio_priv(indio_dev);
0360     st->regmap = regmap;
0361     st->spi = spi;
0362 
0363     indio_dev->info = &ada4250_info;
0364     indio_dev->name = "ada4250";
0365     indio_dev->channels = ada4250_channels;
0366     indio_dev->num_channels = ARRAY_SIZE(ada4250_channels);
0367 
0368     mutex_init(&st->lock);
0369 
0370     ret = ada4250_init(st);
0371     if (ret) {
0372         dev_err(&spi->dev, "ADA4250 init failed\n");
0373         return ret;
0374     }
0375 
0376     return devm_iio_device_register(&spi->dev, indio_dev);
0377 }
0378 
0379 static const struct spi_device_id ada4250_id[] = {
0380     { "ada4250", 0 },
0381     {}
0382 };
0383 MODULE_DEVICE_TABLE(spi, ada4250_id);
0384 
0385 static const struct of_device_id ada4250_of_match[] = {
0386     { .compatible = "adi,ada4250" },
0387     {},
0388 };
0389 MODULE_DEVICE_TABLE(of, ada4250_of_match);
0390 
0391 static struct spi_driver ada4250_driver = {
0392     .driver = {
0393             .name = "ada4250",
0394             .of_match_table = ada4250_of_match,
0395         },
0396     .probe = ada4250_probe,
0397     .id_table = ada4250_id,
0398 };
0399 module_spi_driver(ada4250_driver);
0400 
0401 MODULE_AUTHOR("Antoniu Miclaus <antoniu.miclaus@analog.com");
0402 MODULE_DESCRIPTION("Analog Devices ADA4250");
0403 MODULE_LICENSE("GPL v2");