Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

iio: adc: Add support for ad4062

The AD4060/AD4062 are versatile, 16-bit/12-bit, successive approximation
register (SAR) analog-to-digital converter (ADC) with low-power and
threshold monitoring modes.

Signed-off-by: Jorge Marques <jorge.marques@analog.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Jorge Marques and committed by
Jonathan Cameron
d5284402 1b1ddab0

+832
+1
MAINTAINERS
··· 1439 1439 W: https://ez.analog.com/linux-software-drivers 1440 1440 F: Documentation/devicetree/bindings/iio/adc/adi,ad4062.yaml 1441 1441 F: Documentation/iio/ad4062.rst 1442 + F: drivers/iio/adc/ad4062.c 1442 1443 1443 1444 ANALOG DEVICES INC AD4080 DRIVER 1444 1445 M: Antoniu Miclaus <antoniu.miclaus@analog.com>
+11
drivers/iio/adc/Kconfig
··· 70 70 To compile this driver as a module, choose M here: the module will be 71 71 called ad4030. 72 72 73 + config AD4062 74 + tristate "Analog Devices AD4062 Driver" 75 + depends on I3C 76 + select REGMAP_I3C 77 + help 78 + Say yes here to build support for Analog Devices AD4062 I3C analog 79 + to digital converters (ADC). 80 + 81 + To compile this driver as a module, choose M here: the module will be 82 + called ad4062. 83 + 73 84 config AD4080 74 85 tristate "Analog Devices AD4080 high speed ADC" 75 86 depends on SPI
+1
drivers/iio/adc/Makefile
··· 11 11 obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o 12 12 obj-$(CONFIG_AD4000) += ad4000.o 13 13 obj-$(CONFIG_AD4030) += ad4030.o 14 + obj-$(CONFIG_AD4062) += ad4062.o 14 15 obj-$(CONFIG_AD4080) += ad4080.o 15 16 obj-$(CONFIG_AD4130) += ad4130.o 16 17 obj-$(CONFIG_AD4170_4) += ad4170-4.o
+819
drivers/iio/adc/ad4062.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Analog Devices AD4062 I3C ADC driver 4 + * 5 + * Copyright 2025 Analog Devices Inc. 6 + */ 7 + #include <linux/array_size.h> 8 + #include <linux/bitfield.h> 9 + #include <linux/bitops.h> 10 + #include <linux/completion.h> 11 + #include <linux/delay.h> 12 + #include <linux/err.h> 13 + #include <linux/i3c/device.h> 14 + #include <linux/i3c/master.h> 15 + #include <linux/iio/iio.h> 16 + #include <linux/interrupt.h> 17 + #include <linux/jiffies.h> 18 + #include <linux/math.h> 19 + #include <linux/minmax.h> 20 + #include <linux/pm_runtime.h> 21 + #include <linux/property.h> 22 + #include <linux/regmap.h> 23 + #include <linux/regulator/consumer.h> 24 + #include <linux/string.h> 25 + #include <linux/types.h> 26 + #include <linux/units.h> 27 + #include <linux/unaligned.h> 28 + #include <linux/util_macros.h> 29 + 30 + #define AD4062_REG_INTERFACE_CONFIG_A 0x00 31 + #define AD4062_REG_DEVICE_CONFIG 0x02 32 + #define AD4062_REG_DEVICE_CONFIG_POWER_MODE_MSK GENMASK(1, 0) 33 + #define AD4062_REG_DEVICE_CONFIG_LOW_POWER_MODE 3 34 + #define AD4062_REG_PROD_ID_1 0x05 35 + #define AD4062_REG_DEVICE_GRADE 0x06 36 + #define AD4062_REG_SCRATCH_PAD 0x0A 37 + #define AD4062_REG_VENDOR_H 0x0D 38 + #define AD4062_REG_STREAM_MODE 0x0E 39 + #define AD4062_REG_INTERFACE_STATUS 0x11 40 + #define AD4062_REG_MODE_SET 0x20 41 + #define AD4062_REG_MODE_SET_ENTER_ADC BIT(0) 42 + #define AD4062_REG_ADC_MODES 0x21 43 + #define AD4062_REG_ADC_MODES_MODE_MSK GENMASK(1, 0) 44 + #define AD4062_REG_ADC_CONFIG 0x22 45 + #define AD4062_REG_ADC_CONFIG_REF_EN_MSK BIT(5) 46 + #define AD4062_REG_ADC_CONFIG_SCALE_EN_MSK BIT(4) 47 + #define AD4062_REG_AVG_CONFIG 0x23 48 + #define AD4062_REG_GP_CONF 0x24 49 + #define AD4062_REG_GP_CONF_MODE_MSK_1 GENMASK(6, 4) 50 + #define AD4062_REG_INTR_CONF 0x25 51 + #define AD4062_REG_INTR_CONF_EN_MSK_1 GENMASK(5, 4) 52 + #define AD4062_REG_TIMER_CONFIG 0x27 53 + #define AD4062_REG_TIMER_CONFIG_FS_MASK GENMASK(7, 4) 54 + #define AD4062_REG_MON_VAL 0x2F 55 + #define AD4062_REG_ADC_IBI_EN 0x31 56 + #define AD4062_REG_ADC_IBI_EN_CONV_TRIGGER BIT(2) 57 + #define AD4062_REG_FUSE_CRC 0x40 58 + #define AD4062_REG_DEVICE_STATUS 0x41 59 + #define AD4062_REG_DEVICE_STATUS_DEVICE_RESET BIT(6) 60 + #define AD4062_REG_IBI_STATUS 0x48 61 + #define AD4062_REG_CONV_READ_LSB 0x50 62 + #define AD4062_REG_CONV_TRIGGER_32BITS 0x59 63 + #define AD4062_REG_CONV_AUTO 0x61 64 + #define AD4062_MAX_REG AD4062_REG_CONV_AUTO 65 + 66 + #define AD4062_MON_VAL_MIDDLE_POINT 0x8000 67 + 68 + #define AD4062_I3C_VENDOR 0x0177 69 + #define AD4062_SOFT_RESET 0x81 70 + #define AD4060_PROD_ID 0x7A 71 + #define AD4062_PROD_ID 0x7C 72 + 73 + #define AD4062_GP_DRDY 0x2 74 + 75 + #define AD4062_INTR_EN_NEITHER 0x0 76 + 77 + #define AD4062_TCONV_NS 270 78 + 79 + enum ad4062_operation_mode { 80 + AD4062_SAMPLE_MODE = 0x0, 81 + AD4062_BURST_AVERAGING_MODE = 0x1, 82 + AD4062_MONITOR_MODE = 0x3, 83 + }; 84 + 85 + struct ad4062_chip_info { 86 + const struct iio_chan_spec channels[1]; 87 + const char *name; 88 + u16 prod_id; 89 + u16 avg_max; 90 + }; 91 + 92 + enum { 93 + AD4062_SCAN_TYPE_SAMPLE, 94 + AD4062_SCAN_TYPE_BURST_AVG, 95 + }; 96 + 97 + static const unsigned int ad4062_conversion_freqs[] = { 98 + 2000000, 1000000, 300000, 100000, /* 0 - 3 */ 99 + 33300, 10000, 3000, 500, /* 4 - 7 */ 100 + 333, 250, 200, 166, /* 8 - 11 */ 101 + 140, 124, 111, /* 12 - 15 */ 102 + }; 103 + 104 + struct ad4062_state { 105 + const struct ad4062_chip_info *chip; 106 + const struct ad4062_bus_ops *ops; 107 + enum ad4062_operation_mode mode; 108 + struct completion completion; 109 + struct iio_trigger *trigger; 110 + struct iio_dev *indio_dev; 111 + struct i3c_device *i3cdev; 112 + struct regmap *regmap; 113 + int vref_uV; 114 + unsigned int samp_freqs[ARRAY_SIZE(ad4062_conversion_freqs)]; 115 + u16 sampling_frequency; 116 + u8 oversamp_ratio; 117 + u8 conv_addr; 118 + union { 119 + __be32 be32; 120 + __be16 be16; 121 + } buf __aligned(IIO_DMA_MINALIGN); 122 + }; 123 + 124 + static const struct regmap_range ad4062_regmap_rd_ranges[] = { 125 + regmap_reg_range(AD4062_REG_INTERFACE_CONFIG_A, AD4062_REG_DEVICE_GRADE), 126 + regmap_reg_range(AD4062_REG_SCRATCH_PAD, AD4062_REG_INTERFACE_STATUS), 127 + regmap_reg_range(AD4062_REG_MODE_SET, AD4062_REG_ADC_IBI_EN), 128 + regmap_reg_range(AD4062_REG_FUSE_CRC, AD4062_REG_IBI_STATUS), 129 + regmap_reg_range(AD4062_REG_CONV_READ_LSB, AD4062_REG_CONV_AUTO), 130 + }; 131 + 132 + static const struct regmap_access_table ad4062_regmap_rd_table = { 133 + .yes_ranges = ad4062_regmap_rd_ranges, 134 + .n_yes_ranges = ARRAY_SIZE(ad4062_regmap_rd_ranges), 135 + }; 136 + 137 + static const struct regmap_range ad4062_regmap_wr_ranges[] = { 138 + regmap_reg_range(AD4062_REG_INTERFACE_CONFIG_A, AD4062_REG_DEVICE_CONFIG), 139 + regmap_reg_range(AD4062_REG_SCRATCH_PAD, AD4062_REG_SCRATCH_PAD), 140 + regmap_reg_range(AD4062_REG_STREAM_MODE, AD4062_REG_INTERFACE_STATUS), 141 + regmap_reg_range(AD4062_REG_MODE_SET, AD4062_REG_ADC_IBI_EN), 142 + regmap_reg_range(AD4062_REG_FUSE_CRC, AD4062_REG_DEVICE_STATUS), 143 + }; 144 + 145 + static const struct regmap_access_table ad4062_regmap_wr_table = { 146 + .yes_ranges = ad4062_regmap_wr_ranges, 147 + .n_yes_ranges = ARRAY_SIZE(ad4062_regmap_wr_ranges), 148 + }; 149 + 150 + #define AD4062_CHAN { \ 151 + .type = IIO_VOLTAGE, \ 152 + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_RAW) | \ 153 + BIT(IIO_CHAN_INFO_SCALE) | \ 154 + BIT(IIO_CHAN_INFO_CALIBSCALE) | \ 155 + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ 156 + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 157 + .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ 158 + .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 159 + .indexed = 1, \ 160 + .channel = 0, \ 161 + } 162 + 163 + static const struct ad4062_chip_info ad4060_chip_info = { 164 + .name = "ad4060", 165 + .channels = { AD4062_CHAN }, 166 + .prod_id = AD4060_PROD_ID, 167 + .avg_max = 256, 168 + }; 169 + 170 + static const struct ad4062_chip_info ad4062_chip_info = { 171 + .name = "ad4062", 172 + .channels = { AD4062_CHAN }, 173 + .prod_id = AD4062_PROD_ID, 174 + .avg_max = 4096, 175 + }; 176 + 177 + static int ad4062_set_oversampling_ratio(struct ad4062_state *st, int val, int val2) 178 + { 179 + const u32 _max = st->chip->avg_max; 180 + const u32 _min = 1; 181 + int ret; 182 + 183 + if (!in_range(val, _min, _max) || val2 != 0) 184 + return -EINVAL; 185 + 186 + /* 1 disables oversampling */ 187 + val = ilog2(val); 188 + if (val == 0) { 189 + st->mode = AD4062_SAMPLE_MODE; 190 + } else { 191 + st->mode = AD4062_BURST_AVERAGING_MODE; 192 + ret = regmap_write(st->regmap, AD4062_REG_AVG_CONFIG, val - 1); 193 + if (ret) 194 + return ret; 195 + } 196 + st->oversamp_ratio = val; 197 + 198 + return 0; 199 + } 200 + 201 + static int ad4062_get_oversampling_ratio(struct ad4062_state *st, int *val) 202 + { 203 + int ret, buf; 204 + 205 + if (st->mode == AD4062_SAMPLE_MODE) { 206 + *val = 1; 207 + return 0; 208 + } 209 + 210 + ret = regmap_read(st->regmap, AD4062_REG_AVG_CONFIG, &buf); 211 + if (ret) 212 + return ret; 213 + 214 + *val = BIT(buf + 1); 215 + return 0; 216 + } 217 + 218 + static int ad4062_calc_sampling_frequency(unsigned int fosc, unsigned int oversamp_ratio) 219 + { 220 + /* From datasheet p.31: (n_avg - 1)/fosc + tconv */ 221 + u32 n_avg = BIT(oversamp_ratio) - 1; 222 + u32 period_ns = NSEC_PER_SEC / fosc; 223 + 224 + /* Result is less than 1 Hz */ 225 + if (n_avg >= fosc) 226 + return 1; 227 + 228 + return NSEC_PER_SEC / (n_avg * period_ns + AD4062_TCONV_NS); 229 + } 230 + 231 + static int ad4062_populate_sampling_frequency(struct ad4062_state *st) 232 + { 233 + for (u8 i = 0; i < ARRAY_SIZE(ad4062_conversion_freqs); i++) 234 + st->samp_freqs[i] = 235 + ad4062_calc_sampling_frequency(ad4062_conversion_freqs[i], 236 + st->oversamp_ratio); 237 + return 0; 238 + } 239 + 240 + static int ad4062_get_sampling_frequency(struct ad4062_state *st, int *val) 241 + { 242 + int freq = ad4062_conversion_freqs[st->sampling_frequency]; 243 + 244 + *val = ad4062_calc_sampling_frequency(freq, st->oversamp_ratio); 245 + return IIO_VAL_INT; 246 + } 247 + 248 + static int ad4062_set_sampling_frequency(struct ad4062_state *st, int val, int val2) 249 + { 250 + int ret; 251 + 252 + if (val2 != 0) 253 + return -EINVAL; 254 + 255 + ret = ad4062_populate_sampling_frequency(st); 256 + if (ret) 257 + return ret; 258 + 259 + st->sampling_frequency = 260 + find_closest_descending(val, st->samp_freqs, 261 + ARRAY_SIZE(ad4062_conversion_freqs)); 262 + return 0; 263 + } 264 + 265 + static int ad4062_check_ids(struct ad4062_state *st) 266 + { 267 + struct device *dev = &st->i3cdev->dev; 268 + int ret; 269 + u16 val; 270 + 271 + ret = regmap_bulk_read(st->regmap, AD4062_REG_PROD_ID_1, 272 + &st->buf.be16, sizeof(st->buf.be16)); 273 + if (ret) 274 + return ret; 275 + 276 + val = be16_to_cpu(st->buf.be16); 277 + if (val != st->chip->prod_id) 278 + dev_warn(dev, "Production ID x%x does not match known values", val); 279 + 280 + ret = regmap_bulk_read(st->regmap, AD4062_REG_VENDOR_H, 281 + &st->buf.be16, sizeof(st->buf.be16)); 282 + if (ret) 283 + return ret; 284 + 285 + val = be16_to_cpu(st->buf.be16); 286 + if (val != AD4062_I3C_VENDOR) { 287 + dev_err(dev, "Vendor ID x%x does not match expected value\n", val); 288 + return -ENODEV; 289 + } 290 + 291 + return 0; 292 + } 293 + 294 + static int ad4062_conversion_frequency_set(struct ad4062_state *st, u8 val) 295 + { 296 + return regmap_write(st->regmap, AD4062_REG_TIMER_CONFIG, 297 + FIELD_PREP(AD4062_REG_TIMER_CONFIG_FS_MASK, val)); 298 + } 299 + 300 + static int ad4062_set_operation_mode(struct ad4062_state *st, 301 + enum ad4062_operation_mode mode) 302 + { 303 + int ret; 304 + 305 + ret = ad4062_conversion_frequency_set(st, st->sampling_frequency); 306 + if (ret) 307 + return ret; 308 + 309 + ret = regmap_update_bits(st->regmap, AD4062_REG_ADC_MODES, 310 + AD4062_REG_ADC_MODES_MODE_MSK, mode); 311 + if (ret) 312 + return ret; 313 + 314 + return regmap_write(st->regmap, AD4062_REG_MODE_SET, 315 + AD4062_REG_MODE_SET_ENTER_ADC); 316 + } 317 + 318 + static int ad4062_soft_reset(struct ad4062_state *st) 319 + { 320 + u8 val = AD4062_SOFT_RESET; 321 + int ret; 322 + 323 + ret = regmap_write(st->regmap, AD4062_REG_INTERFACE_CONFIG_A, val); 324 + if (ret) 325 + return ret; 326 + 327 + /* Wait AD4062 treset time, datasheet p8 */ 328 + ndelay(60); 329 + 330 + return 0; 331 + } 332 + 333 + static int ad4062_setup(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, 334 + const bool *ref_sel) 335 + { 336 + struct ad4062_state *st = iio_priv(indio_dev); 337 + int ret; 338 + 339 + ret = regmap_update_bits(st->regmap, AD4062_REG_GP_CONF, 340 + AD4062_REG_GP_CONF_MODE_MSK_1, 341 + FIELD_PREP(AD4062_REG_GP_CONF_MODE_MSK_1, 342 + AD4062_GP_DRDY)); 343 + if (ret) 344 + return ret; 345 + 346 + ret = regmap_update_bits(st->regmap, AD4062_REG_ADC_CONFIG, 347 + AD4062_REG_ADC_CONFIG_REF_EN_MSK, 348 + FIELD_PREP(AD4062_REG_ADC_CONFIG_REF_EN_MSK, 349 + *ref_sel)); 350 + if (ret) 351 + return ret; 352 + 353 + ret = regmap_write(st->regmap, AD4062_REG_DEVICE_STATUS, 354 + AD4062_REG_DEVICE_STATUS_DEVICE_RESET); 355 + if (ret) 356 + return ret; 357 + 358 + ret = regmap_update_bits(st->regmap, AD4062_REG_INTR_CONF, 359 + AD4062_REG_INTR_CONF_EN_MSK_1, 360 + FIELD_PREP(AD4062_REG_INTR_CONF_EN_MSK_1, 361 + AD4062_INTR_EN_NEITHER)); 362 + if (ret) 363 + return ret; 364 + 365 + st->buf.be16 = cpu_to_be16(AD4062_MON_VAL_MIDDLE_POINT); 366 + return regmap_bulk_write(st->regmap, AD4062_REG_MON_VAL, 367 + &st->buf.be16, sizeof(st->buf.be16)); 368 + } 369 + 370 + static irqreturn_t ad4062_irq_handler_drdy(int irq, void *private) 371 + { 372 + struct iio_dev *indio_dev = private; 373 + struct ad4062_state *st = iio_priv(indio_dev); 374 + 375 + complete(&st->completion); 376 + 377 + return IRQ_HANDLED; 378 + } 379 + 380 + static void ad4062_ibi_handler(struct i3c_device *i3cdev, 381 + const struct i3c_ibi_payload *payload) 382 + { 383 + struct ad4062_state *st = i3cdev_get_drvdata(i3cdev); 384 + 385 + complete(&st->completion); 386 + } 387 + 388 + static void ad4062_disable_ibi(void *data) 389 + { 390 + struct i3c_device *i3cdev = data; 391 + 392 + i3c_device_disable_ibi(i3cdev); 393 + } 394 + 395 + static void ad4062_free_ibi(void *data) 396 + { 397 + struct i3c_device *i3cdev = data; 398 + 399 + i3c_device_free_ibi(i3cdev); 400 + } 401 + 402 + static int ad4062_request_ibi(struct i3c_device *i3cdev) 403 + { 404 + const struct i3c_ibi_setup ibireq = { 405 + .max_payload_len = 1, 406 + .num_slots = 1, 407 + .handler = ad4062_ibi_handler, 408 + }; 409 + int ret; 410 + 411 + ret = i3c_device_request_ibi(i3cdev, &ibireq); 412 + if (ret) 413 + return ret; 414 + 415 + ret = devm_add_action_or_reset(&i3cdev->dev, ad4062_free_ibi, i3cdev); 416 + if (ret) 417 + return ret; 418 + 419 + ret = i3c_device_enable_ibi(i3cdev); 420 + if (ret) 421 + return ret; 422 + 423 + return devm_add_action_or_reset(&i3cdev->dev, ad4062_disable_ibi, i3cdev); 424 + } 425 + 426 + static int ad4062_request_irq(struct iio_dev *indio_dev) 427 + { 428 + struct ad4062_state *st = iio_priv(indio_dev); 429 + struct device *dev = &st->i3cdev->dev; 430 + int ret; 431 + 432 + ret = fwnode_irq_get_byname(dev_fwnode(&st->i3cdev->dev), "gp1"); 433 + if (ret == -EPROBE_DEFER) 434 + return ret; 435 + 436 + if (ret < 0) 437 + return regmap_update_bits(st->regmap, AD4062_REG_ADC_IBI_EN, 438 + AD4062_REG_ADC_IBI_EN_CONV_TRIGGER, 439 + AD4062_REG_ADC_IBI_EN_CONV_TRIGGER); 440 + 441 + return devm_request_threaded_irq(dev, ret, 442 + ad4062_irq_handler_drdy, 443 + NULL, IRQF_ONESHOT, indio_dev->name, 444 + indio_dev); 445 + } 446 + 447 + static const int ad4062_oversampling_avail[] = { 448 + 1, 2, 4, 8, 16, 32, 64, 128, /* 0 - 7 */ 449 + 256, 512, 1024, 2048, 4096, /* 8 - 12 */ 450 + }; 451 + 452 + static int ad4062_read_avail(struct iio_dev *indio_dev, 453 + struct iio_chan_spec const *chan, const int **vals, 454 + int *type, int *len, long mask) 455 + { 456 + struct ad4062_state *st = iio_priv(indio_dev); 457 + int ret; 458 + 459 + switch (mask) { 460 + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: 461 + *vals = ad4062_oversampling_avail; 462 + *len = ARRAY_SIZE(ad4062_oversampling_avail); 463 + *len -= st->chip->avg_max == 256 ? 4 : 0; 464 + *type = IIO_VAL_INT; 465 + 466 + return IIO_AVAIL_LIST; 467 + case IIO_CHAN_INFO_SAMP_FREQ: 468 + ret = ad4062_populate_sampling_frequency(st); 469 + if (ret) 470 + return ret; 471 + *vals = st->samp_freqs; 472 + *len = st->oversamp_ratio ? ARRAY_SIZE(ad4062_conversion_freqs) : 1; 473 + *type = IIO_VAL_INT; 474 + 475 + return IIO_AVAIL_LIST; 476 + default: 477 + return -EINVAL; 478 + } 479 + } 480 + 481 + static int ad4062_get_chan_calibscale(struct ad4062_state *st, int *val, int *val2) 482 + { 483 + int ret; 484 + 485 + ret = regmap_bulk_read(st->regmap, AD4062_REG_MON_VAL, 486 + &st->buf.be16, sizeof(st->buf.be16)); 487 + if (ret) 488 + return ret; 489 + 490 + /* From datasheet: code out = code in × mon_val/0x8000 */ 491 + *val = be16_to_cpu(st->buf.be16) * 2; 492 + *val2 = 16; 493 + 494 + return IIO_VAL_FRACTIONAL_LOG2; 495 + } 496 + 497 + static int ad4062_set_chan_calibscale(struct ad4062_state *st, int gain_int, 498 + int gain_frac) 499 + { 500 + /* Divide numerator and denumerator by known great common divider */ 501 + const u32 mon_val = AD4062_MON_VAL_MIDDLE_POINT / 64; 502 + const u32 micro = MICRO / 64; 503 + const u32 gain_fp = gain_int * MICRO + gain_frac; 504 + const u32 reg_val = DIV_ROUND_CLOSEST(gain_fp * mon_val, micro); 505 + int ret; 506 + 507 + /* Checks if the gain is in range and the value fits the field */ 508 + if (gain_int < 0 || gain_int > 1 || reg_val > BIT(16) - 1) 509 + return -EINVAL; 510 + 511 + st->buf.be16 = cpu_to_be16(reg_val); 512 + ret = regmap_bulk_write(st->regmap, AD4062_REG_MON_VAL, 513 + &st->buf.be16, sizeof(st->buf.be16)); 514 + if (ret) 515 + return ret; 516 + 517 + /* Enable scale if gain is not equal to one */ 518 + return regmap_update_bits(st->regmap, AD4062_REG_ADC_CONFIG, 519 + AD4062_REG_ADC_CONFIG_SCALE_EN_MSK, 520 + FIELD_PREP(AD4062_REG_ADC_CONFIG_SCALE_EN_MSK, 521 + !(gain_int == 1 && gain_frac == 0))); 522 + } 523 + 524 + static int ad4062_read_chan_raw(struct ad4062_state *st, int *val) 525 + { 526 + struct i3c_device *i3cdev = st->i3cdev; 527 + struct i3c_priv_xfer xfer_trigger = { 528 + .data.out = &st->conv_addr, 529 + .len = sizeof(st->conv_addr), 530 + .rnw = false, 531 + }; 532 + struct i3c_priv_xfer xfer_sample = { 533 + .data.in = &st->buf.be32, 534 + .len = sizeof(st->buf.be32), 535 + .rnw = true, 536 + }; 537 + int ret; 538 + 539 + PM_RUNTIME_ACQUIRE(&st->i3cdev->dev, pm); 540 + ret = PM_RUNTIME_ACQUIRE_ERR(&pm); 541 + if (ret) 542 + return ret; 543 + 544 + ret = ad4062_set_operation_mode(st, st->mode); 545 + if (ret) 546 + return ret; 547 + 548 + reinit_completion(&st->completion); 549 + /* Change address pointer to trigger conversion */ 550 + st->conv_addr = AD4062_REG_CONV_TRIGGER_32BITS; 551 + ret = i3c_device_do_priv_xfers(i3cdev, &xfer_trigger, 1); 552 + if (ret) 553 + return ret; 554 + /* 555 + * Single sample read should be used only for oversampling and 556 + * sampling frequency pairs that take less than 1 sec. 557 + */ 558 + ret = wait_for_completion_timeout(&st->completion, 559 + msecs_to_jiffies(1000)); 560 + if (!ret) 561 + return -ETIMEDOUT; 562 + 563 + ret = i3c_device_do_priv_xfers(i3cdev, &xfer_sample, 1); 564 + if (ret) 565 + return ret; 566 + *val = be32_to_cpu(st->buf.be32); 567 + return 0; 568 + } 569 + 570 + static int ad4062_read_raw_dispatch(struct ad4062_state *st, 571 + int *val, int *val2, long info) 572 + { 573 + switch (info) { 574 + case IIO_CHAN_INFO_RAW: 575 + return ad4062_read_chan_raw(st, val); 576 + 577 + case IIO_CHAN_INFO_CALIBSCALE: 578 + return ad4062_get_chan_calibscale(st, val, val2); 579 + 580 + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: 581 + return ad4062_get_oversampling_ratio(st, val); 582 + 583 + default: 584 + return -EINVAL; 585 + } 586 + } 587 + 588 + static int ad4062_read_raw(struct iio_dev *indio_dev, 589 + struct iio_chan_spec const *chan, 590 + int *val, int *val2, long info) 591 + { 592 + struct ad4062_state *st = iio_priv(indio_dev); 593 + int ret; 594 + 595 + switch (info) { 596 + case IIO_CHAN_INFO_SAMP_FREQ: 597 + return ad4062_get_sampling_frequency(st, val); 598 + } 599 + 600 + if (!iio_device_claim_direct(indio_dev)) 601 + return -EBUSY; 602 + 603 + ret = ad4062_read_raw_dispatch(st, val, val2, info); 604 + iio_device_release_direct(indio_dev); 605 + return ret ?: IIO_VAL_INT; 606 + } 607 + 608 + static int ad4062_write_raw_dispatch(struct ad4062_state *st, int val, int val2, 609 + long info) 610 + { 611 + switch (info) { 612 + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: 613 + return ad4062_set_oversampling_ratio(st, val, val2); 614 + 615 + case IIO_CHAN_INFO_CALIBSCALE: 616 + return ad4062_set_chan_calibscale(st, val, val2); 617 + 618 + default: 619 + return -EINVAL; 620 + } 621 + }; 622 + 623 + static int ad4062_write_raw(struct iio_dev *indio_dev, 624 + struct iio_chan_spec const *chan, int val, 625 + int val2, long info) 626 + { 627 + struct ad4062_state *st = iio_priv(indio_dev); 628 + int ret; 629 + 630 + switch (info) { 631 + case IIO_CHAN_INFO_SAMP_FREQ: 632 + return ad4062_set_sampling_frequency(st, val, val2); 633 + } 634 + 635 + if (!iio_device_claim_direct(indio_dev)) 636 + return -EBUSY; 637 + 638 + ret = ad4062_write_raw_dispatch(st, val, val2, info); 639 + 640 + iio_device_release_direct(indio_dev); 641 + return ret; 642 + } 643 + 644 + static int ad4062_debugfs_reg_access(struct iio_dev *indio_dev, unsigned int reg, 645 + unsigned int writeval, unsigned int *readval) 646 + { 647 + struct ad4062_state *st = iio_priv(indio_dev); 648 + 649 + if (readval) 650 + return regmap_read(st->regmap, reg, readval); 651 + else 652 + return regmap_write(st->regmap, reg, writeval); 653 + } 654 + 655 + static const struct iio_info ad4062_info = { 656 + .read_raw = ad4062_read_raw, 657 + .write_raw = ad4062_write_raw, 658 + .read_avail = ad4062_read_avail, 659 + .debugfs_reg_access = ad4062_debugfs_reg_access, 660 + }; 661 + 662 + static const struct regmap_config ad4062_regmap_config = { 663 + .name = "ad4062", 664 + .reg_bits = 8, 665 + .val_bits = 8, 666 + .max_register = AD4062_MAX_REG, 667 + .rd_table = &ad4062_regmap_rd_table, 668 + .wr_table = &ad4062_regmap_wr_table, 669 + .can_sleep = true, 670 + }; 671 + 672 + static int ad4062_regulators_get(struct ad4062_state *st, bool *ref_sel) 673 + { 674 + struct device *dev = &st->i3cdev->dev; 675 + int ret; 676 + 677 + ret = devm_regulator_get_enable(dev, "vio"); 678 + if (ret) 679 + return dev_err_probe(dev, ret, "Failed to enable vio voltage\n"); 680 + 681 + st->vref_uV = devm_regulator_get_enable_read_voltage(dev, "ref"); 682 + *ref_sel = st->vref_uV == -ENODEV; 683 + if (st->vref_uV < 0 && !*ref_sel) 684 + return dev_err_probe(dev, st->vref_uV, 685 + "Failed to enable and read ref voltage\n"); 686 + 687 + if (*ref_sel) { 688 + st->vref_uV = devm_regulator_get_enable_read_voltage(dev, "vdd"); 689 + if (st->vref_uV < 0) 690 + return dev_err_probe(dev, st->vref_uV, 691 + "Failed to enable and read vdd voltage\n"); 692 + } else { 693 + ret = devm_regulator_get_enable(dev, "vdd"); 694 + if (ret) 695 + return dev_err_probe(dev, ret, 696 + "Failed to enable vdd regulator\n"); 697 + } 698 + 699 + return 0; 700 + } 701 + 702 + static const struct i3c_device_id ad4062_id_table[] = { 703 + I3C_DEVICE(AD4062_I3C_VENDOR, AD4060_PROD_ID, &ad4060_chip_info), 704 + I3C_DEVICE(AD4062_I3C_VENDOR, AD4062_PROD_ID, &ad4062_chip_info), 705 + { } 706 + }; 707 + MODULE_DEVICE_TABLE(i3c, ad4062_id_table); 708 + 709 + static int ad4062_probe(struct i3c_device *i3cdev) 710 + { 711 + const struct i3c_device_id *id = i3c_device_match_id(i3cdev, ad4062_id_table); 712 + const struct ad4062_chip_info *chip = id->data; 713 + struct device *dev = &i3cdev->dev; 714 + struct iio_dev *indio_dev; 715 + struct ad4062_state *st; 716 + bool ref_sel; 717 + int ret; 718 + 719 + indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); 720 + if (!indio_dev) 721 + return -ENOMEM; 722 + 723 + st = iio_priv(indio_dev); 724 + st->i3cdev = i3cdev; 725 + i3cdev_set_drvdata(i3cdev, st); 726 + init_completion(&st->completion); 727 + 728 + ret = ad4062_regulators_get(st, &ref_sel); 729 + if (ret) 730 + return ret; 731 + 732 + st->regmap = devm_regmap_init_i3c(i3cdev, &ad4062_regmap_config); 733 + if (IS_ERR(st->regmap)) 734 + return dev_err_probe(dev, PTR_ERR(st->regmap), 735 + "Failed to initialize regmap\n"); 736 + 737 + st->mode = AD4062_SAMPLE_MODE; 738 + st->chip = chip; 739 + st->sampling_frequency = 0; 740 + st->oversamp_ratio = 0; 741 + st->indio_dev = indio_dev; 742 + 743 + indio_dev->modes = INDIO_DIRECT_MODE; 744 + indio_dev->num_channels = 1; 745 + indio_dev->info = &ad4062_info; 746 + indio_dev->name = chip->name; 747 + indio_dev->channels = chip->channels; 748 + 749 + ret = ad4062_soft_reset(st); 750 + if (ret) 751 + return dev_err_probe(dev, ret, "AD4062 failed to soft reset\n"); 752 + 753 + ret = ad4062_check_ids(st); 754 + if (ret) 755 + return ret; 756 + 757 + ret = ad4062_setup(indio_dev, indio_dev->channels, &ref_sel); 758 + if (ret) 759 + return ret; 760 + 761 + ret = ad4062_request_irq(indio_dev); 762 + if (ret) 763 + return ret; 764 + 765 + pm_runtime_set_active(dev); 766 + ret = devm_pm_runtime_enable(dev); 767 + if (ret) 768 + return dev_err_probe(dev, ret, "Failed to enable pm_runtime\n"); 769 + 770 + pm_runtime_set_autosuspend_delay(dev, 1000); 771 + pm_runtime_use_autosuspend(dev); 772 + 773 + ret = ad4062_request_ibi(i3cdev); 774 + if (ret) 775 + return dev_err_probe(dev, ret, "Failed to request i3c ibi\n"); 776 + 777 + return devm_iio_device_register(dev, indio_dev); 778 + } 779 + 780 + static int ad4062_runtime_suspend(struct device *dev) 781 + { 782 + struct ad4062_state *st = dev_get_drvdata(dev); 783 + 784 + return regmap_write(st->regmap, AD4062_REG_DEVICE_CONFIG, 785 + FIELD_PREP(AD4062_REG_DEVICE_CONFIG_POWER_MODE_MSK, 786 + AD4062_REG_DEVICE_CONFIG_LOW_POWER_MODE)); 787 + } 788 + 789 + static int ad4062_runtime_resume(struct device *dev) 790 + { 791 + struct ad4062_state *st = dev_get_drvdata(dev); 792 + int ret; 793 + 794 + ret = regmap_clear_bits(st->regmap, AD4062_REG_DEVICE_CONFIG, 795 + AD4062_REG_DEVICE_CONFIG_POWER_MODE_MSK); 796 + if (ret) 797 + return ret; 798 + 799 + /* Wait device functional blocks to power up */ 800 + fsleep(3 * USEC_PER_MSEC); 801 + return 0; 802 + } 803 + 804 + static DEFINE_RUNTIME_DEV_PM_OPS(ad4062_pm_ops, 805 + ad4062_runtime_suspend, ad4062_runtime_resume, NULL); 806 + 807 + static struct i3c_driver ad4062_driver = { 808 + .driver = { 809 + .name = "ad4062", 810 + .pm = pm_ptr(&ad4062_pm_ops), 811 + }, 812 + .probe = ad4062_probe, 813 + .id_table = ad4062_id_table, 814 + }; 815 + module_i3c_driver(ad4062_driver); 816 + 817 + MODULE_AUTHOR("Jorge Marques <jorge.marques@analog.com>"); 818 + MODULE_DESCRIPTION("Analog Devices AD4062"); 819 + MODULE_LICENSE("GPL");