1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * ADMV8818 driver 4 * 5 * Copyright 2021 Analog Devices Inc. 6 */ 7 8#include <linux/bitfield.h> 9#include <linux/bits.h> 10#include <linux/clk.h> 11#include <linux/device.h> 12#include <linux/iio/iio.h> 13#include <linux/module.h> 14#include <linux/mod_devicetable.h> 15#include <linux/mutex.h> 16#include <linux/notifier.h> 17#include <linux/regmap.h> 18#include <linux/spi/spi.h> 19#include <linux/units.h> 20 21/* ADMV8818 Register Map */ 22#define ADMV8818_REG_SPI_CONFIG_A 0x0 23#define ADMV8818_REG_SPI_CONFIG_B 0x1 24#define ADMV8818_REG_CHIPTYPE 0x3 25#define ADMV8818_REG_PRODUCT_ID_L 0x4 26#define ADMV8818_REG_PRODUCT_ID_H 0x5 27#define ADMV8818_REG_FAST_LATCH_POINTER 0x10 28#define ADMV8818_REG_FAST_LATCH_STOP 0x11 29#define ADMV8818_REG_FAST_LATCH_START 0x12 30#define ADMV8818_REG_FAST_LATCH_DIRECTION 0x13 31#define ADMV8818_REG_FAST_LATCH_STATE 0x14 32#define ADMV8818_REG_WR0_SW 0x20 33#define ADMV8818_REG_WR0_FILTER 0x21 34#define ADMV8818_REG_WR1_SW 0x22 35#define ADMV8818_REG_WR1_FILTER 0x23 36#define ADMV8818_REG_WR2_SW 0x24 37#define ADMV8818_REG_WR2_FILTER 0x25 38#define ADMV8818_REG_WR3_SW 0x26 39#define ADMV8818_REG_WR3_FILTER 0x27 40#define ADMV8818_REG_WR4_SW 0x28 41#define ADMV8818_REG_WR4_FILTER 0x29 42#define ADMV8818_REG_LUT0_SW 0x100 43#define ADMV8818_REG_LUT0_FILTER 0x101 44#define ADMV8818_REG_LUT127_SW 0x1FE 45#define ADMV8818_REG_LUT127_FILTER 0x1FF 46 47/* ADMV8818_REG_SPI_CONFIG_A Map */ 48#define ADMV8818_SOFTRESET_N_MSK BIT(7) 49#define ADMV8818_LSB_FIRST_N_MSK BIT(6) 50#define ADMV8818_ENDIAN_N_MSK BIT(5) 51#define ADMV8818_SDOACTIVE_N_MSK BIT(4) 52#define ADMV8818_SDOACTIVE_MSK BIT(3) 53#define ADMV8818_ENDIAN_MSK BIT(2) 54#define ADMV8818_LSBFIRST_MSK BIT(1) 55#define ADMV8818_SOFTRESET_MSK BIT(0) 56 57/* ADMV8818_REG_SPI_CONFIG_B Map */ 58#define ADMV8818_SINGLE_INSTRUCTION_MSK BIT(7) 59#define ADMV8818_CSB_STALL_MSK BIT(6) 60#define ADMV8818_MASTER_SLAVE_RB_MSK BIT(5) 61#define ADMV8818_MASTER_SLAVE_TRANSFER_MSK BIT(0) 62 63/* ADMV8818_REG_WR0_SW Map */ 64#define ADMV8818_SW_IN_SET_WR0_MSK BIT(7) 65#define ADMV8818_SW_OUT_SET_WR0_MSK BIT(6) 66#define ADMV8818_SW_IN_WR0_MSK GENMASK(5, 3) 67#define ADMV8818_SW_OUT_WR0_MSK GENMASK(2, 0) 68 69/* ADMV8818_REG_WR0_FILTER Map */ 70#define ADMV8818_HPF_WR0_MSK GENMASK(7, 4) 71#define ADMV8818_LPF_WR0_MSK GENMASK(3, 0) 72 73enum { 74 ADMV8818_BW_FREQ, 75 ADMV8818_CENTER_FREQ 76}; 77 78enum { 79 ADMV8818_AUTO_MODE, 80 ADMV8818_MANUAL_MODE, 81 ADMV8818_BYPASS_MODE, 82}; 83 84struct admv8818_state { 85 struct spi_device *spi; 86 struct regmap *regmap; 87 struct clk *clkin; 88 struct notifier_block nb; 89 /* Protect against concurrent accesses to the device and data content*/ 90 struct mutex lock; 91 unsigned int filter_mode; 92 u64 cf_hz; 93}; 94 95static const unsigned long long freq_range_hpf[4][2] = { 96 {1750000000ULL, 3550000000ULL}, 97 {3400000000ULL, 7250000000ULL}, 98 {6600000000, 12000000000}, 99 {12500000000, 19900000000} 100}; 101 102static const unsigned long long freq_range_lpf[4][2] = { 103 {2050000000ULL, 3850000000ULL}, 104 {3350000000ULL, 7250000000ULL}, 105 {7000000000, 13000000000}, 106 {12550000000, 18500000000} 107}; 108 109static const struct regmap_config admv8818_regmap_config = { 110 .reg_bits = 16, 111 .val_bits = 8, 112 .read_flag_mask = 0x80, 113 .max_register = 0x1FF, 114}; 115 116static const char * const admv8818_modes[] = { 117 [0] = "auto", 118 [1] = "manual", 119 [2] = "bypass" 120}; 121 122static int __admv8818_hpf_select(struct admv8818_state *st, u64 freq) 123{ 124 unsigned int hpf_step = 0, hpf_band = 0, i, j; 125 u64 freq_step; 126 int ret; 127 128 if (freq < freq_range_hpf[0][0]) 129 goto hpf_write; 130 131 if (freq > freq_range_hpf[3][1]) { 132 hpf_step = 15; 133 hpf_band = 4; 134 135 goto hpf_write; 136 } 137 138 for (i = 0; i < 4; i++) { 139 freq_step = div_u64((freq_range_hpf[i][1] - 140 freq_range_hpf[i][0]), 15); 141 142 if (freq > freq_range_hpf[i][0] && 143 (freq < freq_range_hpf[i][1] + freq_step)) { 144 hpf_band = i + 1; 145 146 for (j = 1; j <= 16; j++) { 147 if (freq < (freq_range_hpf[i][0] + (freq_step * j))) { 148 hpf_step = j - 1; 149 break; 150 } 151 } 152 break; 153 } 154 } 155 156 /* Close HPF frequency gap between 12 and 12.5 GHz */ 157 if (freq >= 12000 * HZ_PER_MHZ && freq <= 12500 * HZ_PER_MHZ) { 158 hpf_band = 3; 159 hpf_step = 15; 160 } 161 162hpf_write: 163 ret = regmap_update_bits(st->regmap, ADMV8818_REG_WR0_SW, 164 ADMV8818_SW_IN_SET_WR0_MSK | 165 ADMV8818_SW_IN_WR0_MSK, 166 FIELD_PREP(ADMV8818_SW_IN_SET_WR0_MSK, 1) | 167 FIELD_PREP(ADMV8818_SW_IN_WR0_MSK, hpf_band)); 168 if (ret) 169 return ret; 170 171 return regmap_update_bits(st->regmap, ADMV8818_REG_WR0_FILTER, 172 ADMV8818_HPF_WR0_MSK, 173 FIELD_PREP(ADMV8818_HPF_WR0_MSK, hpf_step)); 174} 175 176static int admv8818_hpf_select(struct admv8818_state *st, u64 freq) 177{ 178 int ret; 179 180 mutex_lock(&st->lock); 181 ret = __admv8818_hpf_select(st, freq); 182 mutex_unlock(&st->lock); 183 184 return ret; 185} 186 187static int __admv8818_lpf_select(struct admv8818_state *st, u64 freq) 188{ 189 unsigned int lpf_step = 0, lpf_band = 0, i, j; 190 u64 freq_step; 191 int ret; 192 193 if (freq > freq_range_lpf[3][1]) 194 goto lpf_write; 195 196 if (freq < freq_range_lpf[0][0]) { 197 lpf_band = 1; 198 199 goto lpf_write; 200 } 201 202 for (i = 0; i < 4; i++) { 203 if (freq > freq_range_lpf[i][0] && freq < freq_range_lpf[i][1]) { 204 lpf_band = i + 1; 205 freq_step = div_u64((freq_range_lpf[i][1] - freq_range_lpf[i][0]), 15); 206 207 for (j = 0; j <= 15; j++) { 208 if (freq < (freq_range_lpf[i][0] + (freq_step * j))) { 209 lpf_step = j; 210 break; 211 } 212 } 213 break; 214 } 215 } 216 217lpf_write: 218 ret = regmap_update_bits(st->regmap, ADMV8818_REG_WR0_SW, 219 ADMV8818_SW_OUT_SET_WR0_MSK | 220 ADMV8818_SW_OUT_WR0_MSK, 221 FIELD_PREP(ADMV8818_SW_OUT_SET_WR0_MSK, 1) | 222 FIELD_PREP(ADMV8818_SW_OUT_WR0_MSK, lpf_band)); 223 if (ret) 224 return ret; 225 226 return regmap_update_bits(st->regmap, ADMV8818_REG_WR0_FILTER, 227 ADMV8818_LPF_WR0_MSK, 228 FIELD_PREP(ADMV8818_LPF_WR0_MSK, lpf_step)); 229} 230 231static int admv8818_lpf_select(struct admv8818_state *st, u64 freq) 232{ 233 int ret; 234 235 mutex_lock(&st->lock); 236 ret = __admv8818_lpf_select(st, freq); 237 mutex_unlock(&st->lock); 238 239 return ret; 240} 241 242static int admv8818_rfin_band_select(struct admv8818_state *st) 243{ 244 int ret; 245 246 st->cf_hz = clk_get_rate(st->clkin); 247 248 mutex_lock(&st->lock); 249 250 ret = __admv8818_hpf_select(st, st->cf_hz); 251 if (ret) 252 goto exit; 253 254 ret = __admv8818_lpf_select(st, st->cf_hz); 255exit: 256 mutex_unlock(&st->lock); 257 return ret; 258} 259 260static int __admv8818_read_hpf_freq(struct admv8818_state *st, u64 *hpf_freq) 261{ 262 unsigned int data, hpf_band, hpf_state; 263 int ret; 264 265 ret = regmap_read(st->regmap, ADMV8818_REG_WR0_SW, &data); 266 if (ret) 267 return ret; 268 269 hpf_band = FIELD_GET(ADMV8818_SW_IN_WR0_MSK, data); 270 if (!hpf_band || hpf_band > 4) { 271 *hpf_freq = 0; 272 return ret; 273 } 274 275 ret = regmap_read(st->regmap, ADMV8818_REG_WR0_FILTER, &data); 276 if (ret) 277 return ret; 278 279 hpf_state = FIELD_GET(ADMV8818_HPF_WR0_MSK, data); 280 281 *hpf_freq = div_u64(freq_range_hpf[hpf_band - 1][1] - freq_range_hpf[hpf_band - 1][0], 15); 282 *hpf_freq = freq_range_hpf[hpf_band - 1][0] + (*hpf_freq * hpf_state); 283 284 return ret; 285} 286 287static int admv8818_read_hpf_freq(struct admv8818_state *st, u64 *hpf_freq) 288{ 289 int ret; 290 291 mutex_lock(&st->lock); 292 ret = __admv8818_read_hpf_freq(st, hpf_freq); 293 mutex_unlock(&st->lock); 294 295 return ret; 296} 297 298static int __admv8818_read_lpf_freq(struct admv8818_state *st, u64 *lpf_freq) 299{ 300 unsigned int data, lpf_band, lpf_state; 301 int ret; 302 303 ret = regmap_read(st->regmap, ADMV8818_REG_WR0_SW, &data); 304 if (ret) 305 return ret; 306 307 lpf_band = FIELD_GET(ADMV8818_SW_OUT_WR0_MSK, data); 308 if (!lpf_band || lpf_band > 4) { 309 *lpf_freq = 0; 310 return ret; 311 } 312 313 ret = regmap_read(st->regmap, ADMV8818_REG_WR0_FILTER, &data); 314 if (ret) 315 return ret; 316 317 lpf_state = FIELD_GET(ADMV8818_LPF_WR0_MSK, data); 318 319 *lpf_freq = div_u64(freq_range_lpf[lpf_band - 1][1] - freq_range_lpf[lpf_band - 1][0], 15); 320 *lpf_freq = freq_range_lpf[lpf_band - 1][0] + (*lpf_freq * lpf_state); 321 322 return ret; 323} 324 325static int admv8818_read_lpf_freq(struct admv8818_state *st, u64 *lpf_freq) 326{ 327 int ret; 328 329 mutex_lock(&st->lock); 330 ret = __admv8818_read_lpf_freq(st, lpf_freq); 331 mutex_unlock(&st->lock); 332 333 return ret; 334} 335 336static int admv8818_write_raw(struct iio_dev *indio_dev, 337 struct iio_chan_spec const *chan, 338 int val, int val2, long info) 339{ 340 struct admv8818_state *st = iio_priv(indio_dev); 341 342 u64 freq = ((u64)val2 << 32 | (u32)val); 343 344 switch (info) { 345 case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: 346 return admv8818_lpf_select(st, freq); 347 case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY: 348 return admv8818_hpf_select(st, freq); 349 default: 350 return -EINVAL; 351 } 352} 353 354static int admv8818_read_raw(struct iio_dev *indio_dev, 355 struct iio_chan_spec const *chan, 356 int *val, int *val2, long info) 357{ 358 struct admv8818_state *st = iio_priv(indio_dev); 359 int ret; 360 u64 freq; 361 362 switch (info) { 363 case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: 364 ret = admv8818_read_lpf_freq(st, &freq); 365 if (ret) 366 return ret; 367 368 *val = (u32)freq; 369 *val2 = (u32)(freq >> 32); 370 371 return IIO_VAL_INT_64; 372 case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY: 373 ret = admv8818_read_hpf_freq(st, &freq); 374 if (ret) 375 return ret; 376 377 *val = (u32)freq; 378 *val2 = (u32)(freq >> 32); 379 380 return IIO_VAL_INT_64; 381 default: 382 return -EINVAL; 383 } 384} 385 386static int admv8818_reg_access(struct iio_dev *indio_dev, 387 unsigned int reg, 388 unsigned int write_val, 389 unsigned int *read_val) 390{ 391 struct admv8818_state *st = iio_priv(indio_dev); 392 393 if (read_val) 394 return regmap_read(st->regmap, reg, read_val); 395 else 396 return regmap_write(st->regmap, reg, write_val); 397} 398 399static int admv8818_filter_bypass(struct admv8818_state *st) 400{ 401 int ret; 402 403 mutex_lock(&st->lock); 404 405 ret = regmap_update_bits(st->regmap, ADMV8818_REG_WR0_SW, 406 ADMV8818_SW_IN_SET_WR0_MSK | 407 ADMV8818_SW_IN_WR0_MSK | 408 ADMV8818_SW_OUT_SET_WR0_MSK | 409 ADMV8818_SW_OUT_WR0_MSK, 410 FIELD_PREP(ADMV8818_SW_IN_SET_WR0_MSK, 1) | 411 FIELD_PREP(ADMV8818_SW_IN_WR0_MSK, 0) | 412 FIELD_PREP(ADMV8818_SW_OUT_SET_WR0_MSK, 1) | 413 FIELD_PREP(ADMV8818_SW_OUT_WR0_MSK, 0)); 414 if (ret) 415 goto exit; 416 417 ret = regmap_update_bits(st->regmap, ADMV8818_REG_WR0_FILTER, 418 ADMV8818_HPF_WR0_MSK | 419 ADMV8818_LPF_WR0_MSK, 420 FIELD_PREP(ADMV8818_HPF_WR0_MSK, 0) | 421 FIELD_PREP(ADMV8818_LPF_WR0_MSK, 0)); 422 423exit: 424 mutex_unlock(&st->lock); 425 426 return ret; 427} 428 429static int admv8818_get_mode(struct iio_dev *indio_dev, 430 const struct iio_chan_spec *chan) 431{ 432 struct admv8818_state *st = iio_priv(indio_dev); 433 434 return st->filter_mode; 435} 436 437static int admv8818_set_mode(struct iio_dev *indio_dev, 438 const struct iio_chan_spec *chan, 439 unsigned int mode) 440{ 441 struct admv8818_state *st = iio_priv(indio_dev); 442 int ret = 0; 443 444 if (!st->clkin) { 445 if (mode == ADMV8818_MANUAL_MODE) 446 goto set_mode; 447 448 if (mode == ADMV8818_BYPASS_MODE) { 449 ret = admv8818_filter_bypass(st); 450 if (ret) 451 return ret; 452 453 goto set_mode; 454 } 455 456 return -EINVAL; 457 } 458 459 switch (mode) { 460 case ADMV8818_AUTO_MODE: 461 if (st->filter_mode == ADMV8818_AUTO_MODE) 462 return 0; 463 464 ret = clk_prepare_enable(st->clkin); 465 if (ret) 466 return ret; 467 468 ret = clk_notifier_register(st->clkin, &st->nb); 469 if (ret) { 470 clk_disable_unprepare(st->clkin); 471 472 return ret; 473 } 474 475 break; 476 case ADMV8818_MANUAL_MODE: 477 case ADMV8818_BYPASS_MODE: 478 if (st->filter_mode == ADMV8818_AUTO_MODE) { 479 clk_disable_unprepare(st->clkin); 480 481 ret = clk_notifier_unregister(st->clkin, &st->nb); 482 if (ret) 483 return ret; 484 } 485 486 if (mode == ADMV8818_BYPASS_MODE) { 487 ret = admv8818_filter_bypass(st); 488 if (ret) 489 return ret; 490 } 491 492 break; 493 default: 494 return -EINVAL; 495 } 496 497set_mode: 498 st->filter_mode = mode; 499 500 return ret; 501} 502 503static const struct iio_info admv8818_info = { 504 .write_raw = admv8818_write_raw, 505 .read_raw = admv8818_read_raw, 506 .debugfs_reg_access = &admv8818_reg_access, 507}; 508 509static const struct iio_enum admv8818_mode_enum = { 510 .items = admv8818_modes, 511 .num_items = ARRAY_SIZE(admv8818_modes), 512 .get = admv8818_get_mode, 513 .set = admv8818_set_mode, 514}; 515 516static const struct iio_chan_spec_ext_info admv8818_ext_info[] = { 517 IIO_ENUM("filter_mode", IIO_SHARED_BY_ALL, &admv8818_mode_enum), 518 IIO_ENUM_AVAILABLE("filter_mode", IIO_SHARED_BY_ALL, &admv8818_mode_enum), 519 { }, 520}; 521 522#define ADMV8818_CHAN(_channel) { \ 523 .type = IIO_ALTVOLTAGE, \ 524 .output = 1, \ 525 .indexed = 1, \ 526 .channel = _channel, \ 527 .info_mask_separate = \ 528 BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | \ 529 BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY) \ 530} 531 532#define ADMV8818_CHAN_BW_CF(_channel, _admv8818_ext_info) { \ 533 .type = IIO_ALTVOLTAGE, \ 534 .output = 1, \ 535 .indexed = 1, \ 536 .channel = _channel, \ 537 .ext_info = _admv8818_ext_info, \ 538} 539 540static const struct iio_chan_spec admv8818_channels[] = { 541 ADMV8818_CHAN(0), 542 ADMV8818_CHAN_BW_CF(0, admv8818_ext_info), 543}; 544 545static int admv8818_freq_change(struct notifier_block *nb, unsigned long action, void *data) 546{ 547 struct admv8818_state *st = container_of(nb, struct admv8818_state, nb); 548 549 if (action == POST_RATE_CHANGE) 550 return notifier_from_errno(admv8818_rfin_band_select(st)); 551 552 return NOTIFY_OK; 553} 554 555static void admv8818_clk_notifier_unreg(void *data) 556{ 557 struct admv8818_state *st = data; 558 559 if (st->filter_mode == 0) 560 clk_notifier_unregister(st->clkin, &st->nb); 561} 562 563static void admv8818_clk_disable(void *data) 564{ 565 struct admv8818_state *st = data; 566 567 if (st->filter_mode == 0) 568 clk_disable_unprepare(st->clkin); 569} 570 571static int admv8818_init(struct admv8818_state *st) 572{ 573 int ret; 574 struct spi_device *spi = st->spi; 575 unsigned int chip_id; 576 577 ret = regmap_update_bits(st->regmap, ADMV8818_REG_SPI_CONFIG_A, 578 ADMV8818_SOFTRESET_N_MSK | 579 ADMV8818_SOFTRESET_MSK, 580 FIELD_PREP(ADMV8818_SOFTRESET_N_MSK, 1) | 581 FIELD_PREP(ADMV8818_SOFTRESET_MSK, 1)); 582 if (ret) { 583 dev_err(&spi->dev, "ADMV8818 Soft Reset failed.\n"); 584 return ret; 585 } 586 587 ret = regmap_update_bits(st->regmap, ADMV8818_REG_SPI_CONFIG_A, 588 ADMV8818_SDOACTIVE_N_MSK | 589 ADMV8818_SDOACTIVE_MSK, 590 FIELD_PREP(ADMV8818_SDOACTIVE_N_MSK, 1) | 591 FIELD_PREP(ADMV8818_SDOACTIVE_MSK, 1)); 592 if (ret) { 593 dev_err(&spi->dev, "ADMV8818 SDO Enable failed.\n"); 594 return ret; 595 } 596 597 ret = regmap_read(st->regmap, ADMV8818_REG_CHIPTYPE, &chip_id); 598 if (ret) { 599 dev_err(&spi->dev, "ADMV8818 Chip ID read failed.\n"); 600 return ret; 601 } 602 603 if (chip_id != 0x1) { 604 dev_err(&spi->dev, "ADMV8818 Invalid Chip ID.\n"); 605 return -EINVAL; 606 } 607 608 ret = regmap_update_bits(st->regmap, ADMV8818_REG_SPI_CONFIG_B, 609 ADMV8818_SINGLE_INSTRUCTION_MSK, 610 FIELD_PREP(ADMV8818_SINGLE_INSTRUCTION_MSK, 1)); 611 if (ret) { 612 dev_err(&spi->dev, "ADMV8818 Single Instruction failed.\n"); 613 return ret; 614 } 615 616 if (st->clkin) 617 return admv8818_rfin_band_select(st); 618 else 619 return 0; 620} 621 622static int admv8818_clk_setup(struct admv8818_state *st) 623{ 624 struct spi_device *spi = st->spi; 625 int ret; 626 627 st->clkin = devm_clk_get_optional(&spi->dev, "rf_in"); 628 if (IS_ERR(st->clkin)) 629 return dev_err_probe(&spi->dev, PTR_ERR(st->clkin), 630 "failed to get the input clock\n"); 631 else if (!st->clkin) 632 return 0; 633 634 ret = clk_prepare_enable(st->clkin); 635 if (ret) 636 return ret; 637 638 ret = devm_add_action_or_reset(&spi->dev, admv8818_clk_disable, st); 639 if (ret) 640 return ret; 641 642 st->nb.notifier_call = admv8818_freq_change; 643 ret = clk_notifier_register(st->clkin, &st->nb); 644 if (ret < 0) 645 return ret; 646 647 return devm_add_action_or_reset(&spi->dev, admv8818_clk_notifier_unreg, st); 648} 649 650static int admv8818_probe(struct spi_device *spi) 651{ 652 struct iio_dev *indio_dev; 653 struct regmap *regmap; 654 struct admv8818_state *st; 655 int ret; 656 657 indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); 658 if (!indio_dev) 659 return -ENOMEM; 660 661 regmap = devm_regmap_init_spi(spi, &admv8818_regmap_config); 662 if (IS_ERR(regmap)) 663 return PTR_ERR(regmap); 664 665 st = iio_priv(indio_dev); 666 st->regmap = regmap; 667 668 indio_dev->info = &admv8818_info; 669 indio_dev->name = "admv8818"; 670 indio_dev->channels = admv8818_channels; 671 indio_dev->num_channels = ARRAY_SIZE(admv8818_channels); 672 673 st->spi = spi; 674 675 ret = admv8818_clk_setup(st); 676 if (ret) 677 return ret; 678 679 mutex_init(&st->lock); 680 681 ret = admv8818_init(st); 682 if (ret) 683 return ret; 684 685 return devm_iio_device_register(&spi->dev, indio_dev); 686} 687 688static const struct spi_device_id admv8818_id[] = { 689 { "admv8818", 0 }, 690 {} 691}; 692MODULE_DEVICE_TABLE(spi, admv8818_id); 693 694static const struct of_device_id admv8818_of_match[] = { 695 { .compatible = "adi,admv8818" }, 696 {} 697}; 698MODULE_DEVICE_TABLE(of, admv8818_of_match); 699 700static struct spi_driver admv8818_driver = { 701 .driver = { 702 .name = "admv8818", 703 .of_match_table = admv8818_of_match, 704 }, 705 .probe = admv8818_probe, 706 .id_table = admv8818_id, 707}; 708module_spi_driver(admv8818_driver); 709 710MODULE_AUTHOR("Antoniu Miclaus <antoniu.miclaus@analog.com"); 711MODULE_DESCRIPTION("Analog Devices ADMV8818"); 712MODULE_LICENSE("GPL v2"); 713