1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * ADA4250 driver 4 * 5 * Copyright 2022 Analog Devices Inc. 6 */ 7 8 #include <linux/bitfield.h> 9 #include <linux/bits.h> 10 #include <linux/device.h> 11 #include <linux/iio/iio.h> 12 #include <linux/module.h> 13 #include <linux/regmap.h> 14 #include <linux/regulator/consumer.h> 15 #include <linux/spi/spi.h> 16 #include <linux/types.h> 17 #include <linux/units.h> 18 19 /* ADA4250 Register Map */ 20 #define ADA4250_REG_GAIN_MUX 0x00 21 #define ADA4250_REG_REFBUF_EN 0x01 22 #define ADA4250_REG_RESET 0x02 23 #define ADA4250_REG_SNSR_CAL_VAL 0x04 24 #define ADA4250_REG_SNSR_CAL_CNFG 0x05 25 #define ADA4250_REG_DIE_REV 0x18 26 #define ADA4250_REG_CHIP_ID 0x19 27 28 /* ADA4250_REG_GAIN_MUX Map */ 29 #define ADA4250_GAIN_MUX_MSK GENMASK(2, 0) 30 31 /* ADA4250_REG_REFBUF Map */ 32 #define ADA4250_REFBUF_MSK BIT(0) 33 34 /* ADA4250_REG_RESET Map */ 35 #define ADA4250_RESET_MSK BIT(0) 36 37 /* ADA4250_REG_SNSR_CAL_VAL Map */ 38 #define ADA4250_CAL_CFG_BIAS_MSK GENMASK(7, 0) 39 40 /* ADA4250_REG_SNSR_CAL_CNFG Bit Definition */ 41 #define ADA4250_BIAS_SET_MSK GENMASK(3, 2) 42 #define ADA4250_RANGE_SET_MSK GENMASK(1, 0) 43 44 /* Miscellaneous definitions */ 45 #define ADA4250_CHIP_ID 0x4250 46 #define ADA4250_RANGE1 0 47 #define ADA4250_RANGE4 3 48 49 /* ADA4250 current bias set */ 50 enum ada4250_current_bias { 51 ADA4250_BIAS_DISABLED, 52 ADA4250_BIAS_BANDGAP, 53 ADA4250_BIAS_AVDD, 54 }; 55 56 struct ada4250_state { 57 struct spi_device *spi; 58 struct regmap *regmap; 59 /* Protect against concurrent accesses to the device and data content */ 60 struct mutex lock; 61 int avdd_uv; 62 int offset_uv; 63 u8 bias; 64 u8 gain; 65 bool refbuf_en; 66 __le16 reg_val_16 __aligned(IIO_DMA_MINALIGN); 67 }; 68 69 /* ADA4250 Current Bias Source Settings: Disabled, Bandgap Reference, AVDD */ 70 static const int calibbias_table[] = {0, 1, 2}; 71 72 /* ADA4250 Gain (V/V) values: 1, 2, 4, 8, 16, 32, 64, 128 */ 73 static const int hwgain_table[] = {1, 2, 4, 8, 16, 32, 64, 128}; 74 75 static const struct regmap_config ada4250_regmap_config = { 76 .reg_bits = 8, 77 .val_bits = 8, 78 .read_flag_mask = BIT(7), 79 .max_register = 0x1A, 80 }; 81 82 static int ada4250_set_offset_uv(struct iio_dev *indio_dev, 83 const struct iio_chan_spec *chan, 84 int offset_uv) 85 { 86 struct ada4250_state *st = iio_priv(indio_dev); 87 88 int i, ret, x[8], max_vos, min_vos, voltage_v, vlsb = 0; 89 u8 offset_raw, range = ADA4250_RANGE1; 90 u32 lsb_coeff[6] = {1333, 2301, 4283, 8289, 16311, 31599}; 91 92 if (st->bias == 0 || st->bias == 3) 93 return -EINVAL; 94 95 voltage_v = DIV_ROUND_CLOSEST(st->avdd_uv, MICRO); 96 97 if (st->bias == ADA4250_BIAS_AVDD) 98 x[0] = voltage_v; 99 else 100 x[0] = 5; 101 102 x[1] = 126 * (x[0] - 1); 103 104 for (i = 0; i < 6; i++) 105 x[i + 2] = DIV_ROUND_CLOSEST(x[1] * 1000, lsb_coeff[i]); 106 107 if (st->gain == 0) 108 return -EINVAL; 109 110 /* 111 * Compute Range and Voltage per LSB for the Sensor Offset Calibration 112 * Example of computation for Range 1 and Range 2 (Curren Bias Set = AVDD): 113 * Range 1 Range 2 114 * Gain | Max Vos(mV) | LSB(mV) | Max Vos(mV) | LSB(mV) | 115 * 2 | X1*127 | X1=0.126(AVDD-1) | X1*3*127 | X1*3 | 116 * 4 | X2*127 | X2=X1/1.3333 | X2*3*127 | X2*3 | 117 * 8 | X3*127 | X3=X1/2.301 | X3*3*127 | X3*3 | 118 * 16 | X4*127 | X4=X1/4.283 | X4*3*127 | X4*3 | 119 * 32 | X5*127 | X5=X1/8.289 | X5*3*127 | X5*3 | 120 * 64 | X6*127 | X6=X1/16.311 | X6*3*127 | X6*3 | 121 * 128 | X7*127 | X7=X1/31.599 | X7*3*127 | X7*3 | 122 */ 123 for (i = ADA4250_RANGE1; i <= ADA4250_RANGE4; i++) { 124 max_vos = x[st->gain] * 127 * ((1 << (i + 1)) - 1); 125 min_vos = -1 * max_vos; 126 if (offset_uv > min_vos && offset_uv < max_vos) { 127 range = i; 128 vlsb = x[st->gain] * ((1 << (i + 1)) - 1); 129 break; 130 } 131 } 132 133 if (vlsb <= 0) 134 return -EINVAL; 135 136 offset_raw = DIV_ROUND_CLOSEST(abs(offset_uv), vlsb); 137 138 mutex_lock(&st->lock); 139 ret = regmap_update_bits(st->regmap, ADA4250_REG_SNSR_CAL_CNFG, 140 ADA4250_RANGE_SET_MSK, 141 FIELD_PREP(ADA4250_RANGE_SET_MSK, range)); 142 if (ret) 143 goto exit; 144 145 st->offset_uv = offset_raw * vlsb; 146 147 /* 148 * To set the offset calibration value, use bits [6:0] and bit 7 as the 149 * polarity bit (set to "0" for a negative offset and "1" for a positive 150 * offset). 151 */ 152 if (offset_uv < 0) { 153 offset_raw |= BIT(7); 154 st->offset_uv *= (-1); 155 } 156 157 ret = regmap_write(st->regmap, ADA4250_REG_SNSR_CAL_VAL, offset_raw); 158 159 exit: 160 mutex_unlock(&st->lock); 161 162 return ret; 163 } 164 165 static int ada4250_read_raw(struct iio_dev *indio_dev, 166 struct iio_chan_spec const *chan, 167 int *val, int *val2, long info) 168 { 169 struct ada4250_state *st = iio_priv(indio_dev); 170 int ret; 171 172 switch (info) { 173 case IIO_CHAN_INFO_HARDWAREGAIN: 174 ret = regmap_read(st->regmap, ADA4250_REG_GAIN_MUX, val); 175 if (ret) 176 return ret; 177 178 *val = BIT(*val); 179 180 return IIO_VAL_INT; 181 case IIO_CHAN_INFO_OFFSET: 182 *val = st->offset_uv; 183 184 return IIO_VAL_INT; 185 case IIO_CHAN_INFO_CALIBBIAS: 186 ret = regmap_read(st->regmap, ADA4250_REG_SNSR_CAL_CNFG, val); 187 if (ret) 188 return ret; 189 190 *val = FIELD_GET(ADA4250_BIAS_SET_MSK, *val); 191 192 return IIO_VAL_INT; 193 case IIO_CHAN_INFO_SCALE: 194 *val = 1; 195 *val2 = 1000000; 196 197 return IIO_VAL_FRACTIONAL; 198 default: 199 return -EINVAL; 200 } 201 } 202 203 static int ada4250_write_raw(struct iio_dev *indio_dev, 204 struct iio_chan_spec const *chan, 205 int val, int val2, long info) 206 { 207 struct ada4250_state *st = iio_priv(indio_dev); 208 int ret; 209 210 switch (info) { 211 case IIO_CHAN_INFO_HARDWAREGAIN: 212 ret = regmap_write(st->regmap, ADA4250_REG_GAIN_MUX, 213 FIELD_PREP(ADA4250_GAIN_MUX_MSK, ilog2(val))); 214 if (ret) 215 return ret; 216 217 st->gain = ilog2(val); 218 219 return ret; 220 case IIO_CHAN_INFO_OFFSET: 221 return ada4250_set_offset_uv(indio_dev, chan, val); 222 case IIO_CHAN_INFO_CALIBBIAS: 223 ret = regmap_update_bits(st->regmap, ADA4250_REG_SNSR_CAL_CNFG, 224 ADA4250_BIAS_SET_MSK, 225 FIELD_PREP(ADA4250_BIAS_SET_MSK, val)); 226 if (ret) 227 return ret; 228 229 st->bias = val; 230 231 return ret; 232 default: 233 return -EINVAL; 234 } 235 } 236 237 static int ada4250_read_avail(struct iio_dev *indio_dev, 238 struct iio_chan_spec const *chan, 239 const int **vals, int *type, int *length, 240 long mask) 241 { 242 switch (mask) { 243 case IIO_CHAN_INFO_CALIBBIAS: 244 *vals = calibbias_table; 245 *type = IIO_VAL_INT; 246 *length = ARRAY_SIZE(calibbias_table); 247 248 return IIO_AVAIL_LIST; 249 case IIO_CHAN_INFO_HARDWAREGAIN: 250 *vals = hwgain_table; 251 *type = IIO_VAL_INT; 252 *length = ARRAY_SIZE(hwgain_table); 253 254 return IIO_AVAIL_LIST; 255 default: 256 return -EINVAL; 257 } 258 } 259 260 static int ada4250_reg_access(struct iio_dev *indio_dev, 261 unsigned int reg, 262 unsigned int write_val, 263 unsigned int *read_val) 264 { 265 struct ada4250_state *st = iio_priv(indio_dev); 266 267 if (read_val) 268 return regmap_read(st->regmap, reg, read_val); 269 else 270 return regmap_write(st->regmap, reg, write_val); 271 } 272 273 static const struct iio_info ada4250_info = { 274 .read_raw = ada4250_read_raw, 275 .write_raw = ada4250_write_raw, 276 .read_avail = &ada4250_read_avail, 277 .debugfs_reg_access = &ada4250_reg_access, 278 }; 279 280 static const struct iio_chan_spec ada4250_channels[] = { 281 { 282 .type = IIO_VOLTAGE, 283 .output = 1, 284 .indexed = 1, 285 .channel = 0, 286 .info_mask_separate = BIT(IIO_CHAN_INFO_HARDWAREGAIN) | 287 BIT(IIO_CHAN_INFO_OFFSET) | 288 BIT(IIO_CHAN_INFO_CALIBBIAS) | 289 BIT(IIO_CHAN_INFO_SCALE), 290 .info_mask_separate_available = BIT(IIO_CHAN_INFO_CALIBBIAS) | 291 BIT(IIO_CHAN_INFO_HARDWAREGAIN), 292 } 293 }; 294 295 static int ada4250_init(struct ada4250_state *st) 296 { 297 struct device *dev = &st->spi->dev; 298 int ret; 299 u16 chip_id; 300 301 st->refbuf_en = device_property_read_bool(dev, "adi,refbuf-enable"); 302 303 st->avdd_uv = devm_regulator_get_enable_read_voltage(dev, "avdd"); 304 if (st->avdd_uv < 0) 305 return dev_err_probe(dev, st->avdd_uv, 306 "failed to get the AVDD voltage\n"); 307 308 ret = regmap_write(st->regmap, ADA4250_REG_RESET, 309 FIELD_PREP(ADA4250_RESET_MSK, 1)); 310 if (ret) 311 return ret; 312 313 ret = regmap_bulk_read(st->regmap, ADA4250_REG_CHIP_ID, &st->reg_val_16, 314 sizeof(st->reg_val_16)); 315 if (ret) 316 return ret; 317 318 chip_id = le16_to_cpu(st->reg_val_16); 319 320 if (chip_id != ADA4250_CHIP_ID) 321 dev_info(dev, "Invalid chip ID: 0x%02X.\n", chip_id); 322 323 return regmap_write(st->regmap, ADA4250_REG_REFBUF_EN, 324 FIELD_PREP(ADA4250_REFBUF_MSK, st->refbuf_en)); 325 } 326 327 static int ada4250_probe(struct spi_device *spi) 328 { 329 struct iio_dev *indio_dev; 330 struct regmap *regmap; 331 struct ada4250_state *st; 332 int ret; 333 334 indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); 335 if (!indio_dev) 336 return -ENOMEM; 337 338 regmap = devm_regmap_init_spi(spi, &ada4250_regmap_config); 339 if (IS_ERR(regmap)) 340 return PTR_ERR(regmap); 341 342 st = iio_priv(indio_dev); 343 st->regmap = regmap; 344 st->spi = spi; 345 346 indio_dev->info = &ada4250_info; 347 indio_dev->name = "ada4250"; 348 indio_dev->channels = ada4250_channels; 349 indio_dev->num_channels = ARRAY_SIZE(ada4250_channels); 350 351 mutex_init(&st->lock); 352 353 ret = ada4250_init(st); 354 if (ret) 355 return dev_err_probe(&spi->dev, ret, "ADA4250 init failed\n"); 356 357 return devm_iio_device_register(&spi->dev, indio_dev); 358 } 359 360 static const struct spi_device_id ada4250_id[] = { 361 { "ada4250", 0 }, 362 { } 363 }; 364 MODULE_DEVICE_TABLE(spi, ada4250_id); 365 366 static const struct of_device_id ada4250_of_match[] = { 367 { .compatible = "adi,ada4250" }, 368 { } 369 }; 370 MODULE_DEVICE_TABLE(of, ada4250_of_match); 371 372 static struct spi_driver ada4250_driver = { 373 .driver = { 374 .name = "ada4250", 375 .of_match_table = ada4250_of_match, 376 }, 377 .probe = ada4250_probe, 378 .id_table = ada4250_id, 379 }; 380 module_spi_driver(ada4250_driver); 381 382 MODULE_AUTHOR("Antoniu Miclaus <antoniu.miclaus@analog.com"); 383 MODULE_DESCRIPTION("Analog Devices ADA4250"); 384 MODULE_LICENSE("GPL v2"); 385