0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/bitfield.h>
0009 #include <linux/bits.h>
0010 #include <linux/clk.h>
0011 #include <linux/device.h>
0012 #include <linux/iio/iio.h>
0013 #include <linux/module.h>
0014 #include <linux/mod_devicetable.h>
0015 #include <linux/mutex.h>
0016 #include <linux/notifier.h>
0017 #include <linux/regmap.h>
0018 #include <linux/spi/spi.h>
0019 #include <linux/units.h>
0020
0021
0022 #define ADMV8818_REG_SPI_CONFIG_A 0x0
0023 #define ADMV8818_REG_SPI_CONFIG_B 0x1
0024 #define ADMV8818_REG_CHIPTYPE 0x3
0025 #define ADMV8818_REG_PRODUCT_ID_L 0x4
0026 #define ADMV8818_REG_PRODUCT_ID_H 0x5
0027 #define ADMV8818_REG_FAST_LATCH_POINTER 0x10
0028 #define ADMV8818_REG_FAST_LATCH_STOP 0x11
0029 #define ADMV8818_REG_FAST_LATCH_START 0x12
0030 #define ADMV8818_REG_FAST_LATCH_DIRECTION 0x13
0031 #define ADMV8818_REG_FAST_LATCH_STATE 0x14
0032 #define ADMV8818_REG_WR0_SW 0x20
0033 #define ADMV8818_REG_WR0_FILTER 0x21
0034 #define ADMV8818_REG_WR1_SW 0x22
0035 #define ADMV8818_REG_WR1_FILTER 0x23
0036 #define ADMV8818_REG_WR2_SW 0x24
0037 #define ADMV8818_REG_WR2_FILTER 0x25
0038 #define ADMV8818_REG_WR3_SW 0x26
0039 #define ADMV8818_REG_WR3_FILTER 0x27
0040 #define ADMV8818_REG_WR4_SW 0x28
0041 #define ADMV8818_REG_WR4_FILTER 0x29
0042 #define ADMV8818_REG_LUT0_SW 0x100
0043 #define ADMV8818_REG_LUT0_FILTER 0x101
0044 #define ADMV8818_REG_LUT127_SW 0x1FE
0045 #define ADMV8818_REG_LUT127_FILTER 0x1FF
0046
0047
0048 #define ADMV8818_SOFTRESET_N_MSK BIT(7)
0049 #define ADMV8818_LSB_FIRST_N_MSK BIT(6)
0050 #define ADMV8818_ENDIAN_N_MSK BIT(5)
0051 #define ADMV8818_SDOACTIVE_N_MSK BIT(4)
0052 #define ADMV8818_SDOACTIVE_MSK BIT(3)
0053 #define ADMV8818_ENDIAN_MSK BIT(2)
0054 #define ADMV8818_LSBFIRST_MSK BIT(1)
0055 #define ADMV8818_SOFTRESET_MSK BIT(0)
0056
0057
0058 #define ADMV8818_SINGLE_INSTRUCTION_MSK BIT(7)
0059 #define ADMV8818_CSB_STALL_MSK BIT(6)
0060 #define ADMV8818_MASTER_SLAVE_RB_MSK BIT(5)
0061 #define ADMV8818_MASTER_SLAVE_TRANSFER_MSK BIT(0)
0062
0063
0064 #define ADMV8818_SW_IN_SET_WR0_MSK BIT(7)
0065 #define ADMV8818_SW_OUT_SET_WR0_MSK BIT(6)
0066 #define ADMV8818_SW_IN_WR0_MSK GENMASK(5, 3)
0067 #define ADMV8818_SW_OUT_WR0_MSK GENMASK(2, 0)
0068
0069
0070 #define ADMV8818_HPF_WR0_MSK GENMASK(7, 4)
0071 #define ADMV8818_LPF_WR0_MSK GENMASK(3, 0)
0072
0073 enum {
0074 ADMV8818_BW_FREQ,
0075 ADMV8818_CENTER_FREQ
0076 };
0077
0078 enum {
0079 ADMV8818_AUTO_MODE,
0080 ADMV8818_MANUAL_MODE,
0081 };
0082
0083 struct admv8818_state {
0084 struct spi_device *spi;
0085 struct regmap *regmap;
0086 struct clk *clkin;
0087 struct notifier_block nb;
0088
0089 struct mutex lock;
0090 unsigned int filter_mode;
0091 u64 cf_hz;
0092 };
0093
0094 static const unsigned long long freq_range_hpf[4][2] = {
0095 {1750000000ULL, 3550000000ULL},
0096 {3400000000ULL, 7250000000ULL},
0097 {6600000000, 12000000000},
0098 {12500000000, 19900000000}
0099 };
0100
0101 static const unsigned long long freq_range_lpf[4][2] = {
0102 {2050000000ULL, 3850000000ULL},
0103 {3350000000ULL, 7250000000ULL},
0104 {7000000000, 13000000000},
0105 {12550000000, 18500000000}
0106 };
0107
0108 static const struct regmap_config admv8818_regmap_config = {
0109 .reg_bits = 16,
0110 .val_bits = 8,
0111 .read_flag_mask = 0x80,
0112 .max_register = 0x1FF,
0113 };
0114
0115 static const char * const admv8818_modes[] = {
0116 [0] = "auto",
0117 [1] = "manual"
0118 };
0119
0120 static int __admv8818_hpf_select(struct admv8818_state *st, u64 freq)
0121 {
0122 unsigned int hpf_step = 0, hpf_band = 0, i, j;
0123 u64 freq_step;
0124 int ret;
0125
0126 if (freq < freq_range_hpf[0][0])
0127 goto hpf_write;
0128
0129 if (freq > freq_range_hpf[3][1]) {
0130 hpf_step = 15;
0131 hpf_band = 4;
0132
0133 goto hpf_write;
0134 }
0135
0136 for (i = 0; i < 4; i++) {
0137 freq_step = div_u64((freq_range_hpf[i][1] -
0138 freq_range_hpf[i][0]), 15);
0139
0140 if (freq > freq_range_hpf[i][0] &&
0141 (freq < freq_range_hpf[i][1] + freq_step)) {
0142 hpf_band = i + 1;
0143
0144 for (j = 1; j <= 16; j++) {
0145 if (freq < (freq_range_hpf[i][0] + (freq_step * j))) {
0146 hpf_step = j - 1;
0147 break;
0148 }
0149 }
0150 break;
0151 }
0152 }
0153
0154
0155 if (freq >= 12000 * HZ_PER_MHZ && freq <= 12500 * HZ_PER_MHZ) {
0156 hpf_band = 3;
0157 hpf_step = 15;
0158 }
0159
0160 hpf_write:
0161 ret = regmap_update_bits(st->regmap, ADMV8818_REG_WR0_SW,
0162 ADMV8818_SW_IN_SET_WR0_MSK |
0163 ADMV8818_SW_IN_WR0_MSK,
0164 FIELD_PREP(ADMV8818_SW_IN_SET_WR0_MSK, 1) |
0165 FIELD_PREP(ADMV8818_SW_IN_WR0_MSK, hpf_band));
0166 if (ret)
0167 return ret;
0168
0169 return regmap_update_bits(st->regmap, ADMV8818_REG_WR0_FILTER,
0170 ADMV8818_HPF_WR0_MSK,
0171 FIELD_PREP(ADMV8818_HPF_WR0_MSK, hpf_step));
0172 }
0173
0174 static int admv8818_hpf_select(struct admv8818_state *st, u64 freq)
0175 {
0176 int ret;
0177
0178 mutex_lock(&st->lock);
0179 ret = __admv8818_hpf_select(st, freq);
0180 mutex_unlock(&st->lock);
0181
0182 return ret;
0183 }
0184
0185 static int __admv8818_lpf_select(struct admv8818_state *st, u64 freq)
0186 {
0187 unsigned int lpf_step = 0, lpf_band = 0, i, j;
0188 u64 freq_step;
0189 int ret;
0190
0191 if (freq > freq_range_lpf[3][1])
0192 goto lpf_write;
0193
0194 if (freq < freq_range_lpf[0][0]) {
0195 lpf_band = 1;
0196
0197 goto lpf_write;
0198 }
0199
0200 for (i = 0; i < 4; i++) {
0201 if (freq > freq_range_lpf[i][0] && freq < freq_range_lpf[i][1]) {
0202 lpf_band = i + 1;
0203 freq_step = div_u64((freq_range_lpf[i][1] - freq_range_lpf[i][0]), 15);
0204
0205 for (j = 0; j <= 15; j++) {
0206 if (freq < (freq_range_lpf[i][0] + (freq_step * j))) {
0207 lpf_step = j;
0208 break;
0209 }
0210 }
0211 break;
0212 }
0213 }
0214
0215 lpf_write:
0216 ret = regmap_update_bits(st->regmap, ADMV8818_REG_WR0_SW,
0217 ADMV8818_SW_OUT_SET_WR0_MSK |
0218 ADMV8818_SW_OUT_WR0_MSK,
0219 FIELD_PREP(ADMV8818_SW_OUT_SET_WR0_MSK, 1) |
0220 FIELD_PREP(ADMV8818_SW_OUT_WR0_MSK, lpf_band));
0221 if (ret)
0222 return ret;
0223
0224 return regmap_update_bits(st->regmap, ADMV8818_REG_WR0_FILTER,
0225 ADMV8818_LPF_WR0_MSK,
0226 FIELD_PREP(ADMV8818_LPF_WR0_MSK, lpf_step));
0227 }
0228
0229 static int admv8818_lpf_select(struct admv8818_state *st, u64 freq)
0230 {
0231 int ret;
0232
0233 mutex_lock(&st->lock);
0234 ret = __admv8818_lpf_select(st, freq);
0235 mutex_unlock(&st->lock);
0236
0237 return ret;
0238 }
0239
0240 static int admv8818_rfin_band_select(struct admv8818_state *st)
0241 {
0242 int ret;
0243
0244 st->cf_hz = clk_get_rate(st->clkin);
0245
0246 mutex_lock(&st->lock);
0247
0248 ret = __admv8818_hpf_select(st, st->cf_hz);
0249 if (ret)
0250 goto exit;
0251
0252 ret = __admv8818_lpf_select(st, st->cf_hz);
0253 exit:
0254 mutex_unlock(&st->lock);
0255 return ret;
0256 }
0257
0258 static int __admv8818_read_hpf_freq(struct admv8818_state *st, u64 *hpf_freq)
0259 {
0260 unsigned int data, hpf_band, hpf_state;
0261 int ret;
0262
0263 ret = regmap_read(st->regmap, ADMV8818_REG_WR0_SW, &data);
0264 if (ret)
0265 return ret;
0266
0267 hpf_band = FIELD_GET(ADMV8818_SW_IN_WR0_MSK, data);
0268 if (!hpf_band) {
0269 *hpf_freq = 0;
0270 return ret;
0271 }
0272
0273 ret = regmap_read(st->regmap, ADMV8818_REG_WR0_FILTER, &data);
0274 if (ret)
0275 return ret;
0276
0277 hpf_state = FIELD_GET(ADMV8818_HPF_WR0_MSK, data);
0278
0279 *hpf_freq = div_u64(freq_range_hpf[hpf_band - 1][1] - freq_range_hpf[hpf_band - 1][0], 15);
0280 *hpf_freq = freq_range_hpf[hpf_band - 1][0] + (*hpf_freq * hpf_state);
0281
0282 return ret;
0283 }
0284
0285 static int admv8818_read_hpf_freq(struct admv8818_state *st, u64 *hpf_freq)
0286 {
0287 int ret;
0288
0289 mutex_lock(&st->lock);
0290 ret = __admv8818_read_hpf_freq(st, hpf_freq);
0291 mutex_unlock(&st->lock);
0292
0293 return ret;
0294 }
0295
0296 static int __admv8818_read_lpf_freq(struct admv8818_state *st, u64 *lpf_freq)
0297 {
0298 unsigned int data, lpf_band, lpf_state;
0299 int ret;
0300
0301 ret = regmap_read(st->regmap, ADMV8818_REG_WR0_SW, &data);
0302 if (ret)
0303 return ret;
0304
0305 lpf_band = FIELD_GET(ADMV8818_SW_OUT_WR0_MSK, data);
0306 if (!lpf_band) {
0307 *lpf_freq = 0;
0308 return ret;
0309 }
0310
0311 ret = regmap_read(st->regmap, ADMV8818_REG_WR0_FILTER, &data);
0312 if (ret)
0313 return ret;
0314
0315 lpf_state = FIELD_GET(ADMV8818_LPF_WR0_MSK, data);
0316
0317 *lpf_freq = div_u64(freq_range_lpf[lpf_band - 1][1] - freq_range_lpf[lpf_band - 1][0], 15);
0318 *lpf_freq = freq_range_lpf[lpf_band - 1][0] + (*lpf_freq * lpf_state);
0319
0320 return ret;
0321 }
0322
0323 static int admv8818_read_lpf_freq(struct admv8818_state *st, u64 *lpf_freq)
0324 {
0325 int ret;
0326
0327 mutex_lock(&st->lock);
0328 ret = __admv8818_read_lpf_freq(st, lpf_freq);
0329 mutex_unlock(&st->lock);
0330
0331 return ret;
0332 }
0333
0334 static int admv8818_write_raw(struct iio_dev *indio_dev,
0335 struct iio_chan_spec const *chan,
0336 int val, int val2, long info)
0337 {
0338 struct admv8818_state *st = iio_priv(indio_dev);
0339
0340 u64 freq = ((u64)val2 << 32 | (u32)val);
0341
0342 switch (info) {
0343 case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
0344 return admv8818_lpf_select(st, freq);
0345 case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
0346 return admv8818_hpf_select(st, freq);
0347 default:
0348 return -EINVAL;
0349 }
0350 }
0351
0352 static int admv8818_read_raw(struct iio_dev *indio_dev,
0353 struct iio_chan_spec const *chan,
0354 int *val, int *val2, long info)
0355 {
0356 struct admv8818_state *st = iio_priv(indio_dev);
0357 int ret;
0358 u64 freq;
0359
0360 switch (info) {
0361 case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
0362 ret = admv8818_read_lpf_freq(st, &freq);
0363 if (ret)
0364 return ret;
0365
0366 *val = (u32)freq;
0367 *val2 = (u32)(freq >> 32);
0368
0369 return IIO_VAL_INT_64;
0370 case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
0371 ret = admv8818_read_hpf_freq(st, &freq);
0372 if (ret)
0373 return ret;
0374
0375 *val = (u32)freq;
0376 *val2 = (u32)(freq >> 32);
0377
0378 return IIO_VAL_INT_64;
0379 default:
0380 return -EINVAL;
0381 }
0382 }
0383
0384 static int admv8818_reg_access(struct iio_dev *indio_dev,
0385 unsigned int reg,
0386 unsigned int write_val,
0387 unsigned int *read_val)
0388 {
0389 struct admv8818_state *st = iio_priv(indio_dev);
0390
0391 if (read_val)
0392 return regmap_read(st->regmap, reg, read_val);
0393 else
0394 return regmap_write(st->regmap, reg, write_val);
0395 }
0396
0397 static int admv8818_get_mode(struct iio_dev *indio_dev,
0398 const struct iio_chan_spec *chan)
0399 {
0400 struct admv8818_state *st = iio_priv(indio_dev);
0401
0402 return st->filter_mode;
0403 }
0404
0405 static int admv8818_set_mode(struct iio_dev *indio_dev,
0406 const struct iio_chan_spec *chan,
0407 unsigned int mode)
0408 {
0409 struct admv8818_state *st = iio_priv(indio_dev);
0410 int ret = 0;
0411
0412 if (!st->clkin) {
0413 if (mode == ADMV8818_MANUAL_MODE)
0414 return 0;
0415
0416 return -EINVAL;
0417 }
0418
0419 switch (mode) {
0420 case ADMV8818_AUTO_MODE:
0421 if (!st->filter_mode)
0422 return 0;
0423
0424 ret = clk_prepare_enable(st->clkin);
0425 if (ret)
0426 return ret;
0427
0428 ret = clk_notifier_register(st->clkin, &st->nb);
0429 if (ret) {
0430 clk_disable_unprepare(st->clkin);
0431
0432 return ret;
0433 }
0434
0435 break;
0436 case ADMV8818_MANUAL_MODE:
0437 if (st->filter_mode)
0438 return 0;
0439
0440 clk_disable_unprepare(st->clkin);
0441
0442 ret = clk_notifier_unregister(st->clkin, &st->nb);
0443 if (ret)
0444 return ret;
0445
0446 break;
0447 default:
0448 return -EINVAL;
0449 }
0450
0451 st->filter_mode = mode;
0452
0453 return ret;
0454 }
0455
0456 static const struct iio_info admv8818_info = {
0457 .write_raw = admv8818_write_raw,
0458 .read_raw = admv8818_read_raw,
0459 .debugfs_reg_access = &admv8818_reg_access,
0460 };
0461
0462 static const struct iio_enum admv8818_mode_enum = {
0463 .items = admv8818_modes,
0464 .num_items = ARRAY_SIZE(admv8818_modes),
0465 .get = admv8818_get_mode,
0466 .set = admv8818_set_mode,
0467 };
0468
0469 static const struct iio_chan_spec_ext_info admv8818_ext_info[] = {
0470 IIO_ENUM("filter_mode", IIO_SHARED_BY_ALL, &admv8818_mode_enum),
0471 IIO_ENUM_AVAILABLE("filter_mode", IIO_SHARED_BY_ALL, &admv8818_mode_enum),
0472 { },
0473 };
0474
0475 #define ADMV8818_CHAN(_channel) { \
0476 .type = IIO_ALTVOLTAGE, \
0477 .output = 1, \
0478 .indexed = 1, \
0479 .channel = _channel, \
0480 .info_mask_separate = \
0481 BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | \
0482 BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY) \
0483 }
0484
0485 #define ADMV8818_CHAN_BW_CF(_channel, _admv8818_ext_info) { \
0486 .type = IIO_ALTVOLTAGE, \
0487 .output = 1, \
0488 .indexed = 1, \
0489 .channel = _channel, \
0490 .ext_info = _admv8818_ext_info, \
0491 }
0492
0493 static const struct iio_chan_spec admv8818_channels[] = {
0494 ADMV8818_CHAN(0),
0495 ADMV8818_CHAN_BW_CF(0, admv8818_ext_info),
0496 };
0497
0498 static int admv8818_freq_change(struct notifier_block *nb, unsigned long action, void *data)
0499 {
0500 struct admv8818_state *st = container_of(nb, struct admv8818_state, nb);
0501
0502 if (action == POST_RATE_CHANGE)
0503 return notifier_from_errno(admv8818_rfin_band_select(st));
0504
0505 return NOTIFY_OK;
0506 }
0507
0508 static void admv8818_clk_notifier_unreg(void *data)
0509 {
0510 struct admv8818_state *st = data;
0511
0512 if (st->filter_mode == 0)
0513 clk_notifier_unregister(st->clkin, &st->nb);
0514 }
0515
0516 static void admv8818_clk_disable(void *data)
0517 {
0518 struct admv8818_state *st = data;
0519
0520 if (st->filter_mode == 0)
0521 clk_disable_unprepare(st->clkin);
0522 }
0523
0524 static int admv8818_init(struct admv8818_state *st)
0525 {
0526 int ret;
0527 struct spi_device *spi = st->spi;
0528 unsigned int chip_id;
0529
0530 ret = regmap_update_bits(st->regmap, ADMV8818_REG_SPI_CONFIG_A,
0531 ADMV8818_SOFTRESET_N_MSK |
0532 ADMV8818_SOFTRESET_MSK,
0533 FIELD_PREP(ADMV8818_SOFTRESET_N_MSK, 1) |
0534 FIELD_PREP(ADMV8818_SOFTRESET_MSK, 1));
0535 if (ret) {
0536 dev_err(&spi->dev, "ADMV8818 Soft Reset failed.\n");
0537 return ret;
0538 }
0539
0540 ret = regmap_update_bits(st->regmap, ADMV8818_REG_SPI_CONFIG_A,
0541 ADMV8818_SDOACTIVE_N_MSK |
0542 ADMV8818_SDOACTIVE_MSK,
0543 FIELD_PREP(ADMV8818_SDOACTIVE_N_MSK, 1) |
0544 FIELD_PREP(ADMV8818_SDOACTIVE_MSK, 1));
0545 if (ret) {
0546 dev_err(&spi->dev, "ADMV8818 SDO Enable failed.\n");
0547 return ret;
0548 }
0549
0550 ret = regmap_read(st->regmap, ADMV8818_REG_CHIPTYPE, &chip_id);
0551 if (ret) {
0552 dev_err(&spi->dev, "ADMV8818 Chip ID read failed.\n");
0553 return ret;
0554 }
0555
0556 if (chip_id != 0x1) {
0557 dev_err(&spi->dev, "ADMV8818 Invalid Chip ID.\n");
0558 return -EINVAL;
0559 }
0560
0561 ret = regmap_update_bits(st->regmap, ADMV8818_REG_SPI_CONFIG_B,
0562 ADMV8818_SINGLE_INSTRUCTION_MSK,
0563 FIELD_PREP(ADMV8818_SINGLE_INSTRUCTION_MSK, 1));
0564 if (ret) {
0565 dev_err(&spi->dev, "ADMV8818 Single Instruction failed.\n");
0566 return ret;
0567 }
0568
0569 if (st->clkin)
0570 return admv8818_rfin_band_select(st);
0571 else
0572 return 0;
0573 }
0574
0575 static int admv8818_clk_setup(struct admv8818_state *st)
0576 {
0577 struct spi_device *spi = st->spi;
0578 int ret;
0579
0580 st->clkin = devm_clk_get_optional(&spi->dev, "rf_in");
0581 if (IS_ERR(st->clkin))
0582 return dev_err_probe(&spi->dev, PTR_ERR(st->clkin),
0583 "failed to get the input clock\n");
0584 else if (!st->clkin)
0585 return 0;
0586
0587 ret = clk_prepare_enable(st->clkin);
0588 if (ret)
0589 return ret;
0590
0591 ret = devm_add_action_or_reset(&spi->dev, admv8818_clk_disable, st);
0592 if (ret)
0593 return ret;
0594
0595 st->nb.notifier_call = admv8818_freq_change;
0596 ret = clk_notifier_register(st->clkin, &st->nb);
0597 if (ret < 0)
0598 return ret;
0599
0600 return devm_add_action_or_reset(&spi->dev, admv8818_clk_notifier_unreg, st);
0601 }
0602
0603 static int admv8818_probe(struct spi_device *spi)
0604 {
0605 struct iio_dev *indio_dev;
0606 struct regmap *regmap;
0607 struct admv8818_state *st;
0608 int ret;
0609
0610 indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
0611 if (!indio_dev)
0612 return -ENOMEM;
0613
0614 regmap = devm_regmap_init_spi(spi, &admv8818_regmap_config);
0615 if (IS_ERR(regmap))
0616 return PTR_ERR(regmap);
0617
0618 st = iio_priv(indio_dev);
0619 st->regmap = regmap;
0620
0621 indio_dev->info = &admv8818_info;
0622 indio_dev->name = "admv8818";
0623 indio_dev->channels = admv8818_channels;
0624 indio_dev->num_channels = ARRAY_SIZE(admv8818_channels);
0625
0626 st->spi = spi;
0627
0628 ret = admv8818_clk_setup(st);
0629 if (ret)
0630 return ret;
0631
0632 mutex_init(&st->lock);
0633
0634 ret = admv8818_init(st);
0635 if (ret)
0636 return ret;
0637
0638 return devm_iio_device_register(&spi->dev, indio_dev);
0639 }
0640
0641 static const struct spi_device_id admv8818_id[] = {
0642 { "admv8818", 0 },
0643 {}
0644 };
0645 MODULE_DEVICE_TABLE(spi, admv8818_id);
0646
0647 static const struct of_device_id admv8818_of_match[] = {
0648 { .compatible = "adi,admv8818" },
0649 {}
0650 };
0651 MODULE_DEVICE_TABLE(of, admv8818_of_match);
0652
0653 static struct spi_driver admv8818_driver = {
0654 .driver = {
0655 .name = "admv8818",
0656 .of_match_table = admv8818_of_match,
0657 },
0658 .probe = admv8818_probe,
0659 .id_table = admv8818_id,
0660 };
0661 module_spi_driver(admv8818_driver);
0662
0663 MODULE_AUTHOR("Antoniu Miclaus <antoniu.miclaus@analog.com");
0664 MODULE_DESCRIPTION("Analog Devices ADMV8818");
0665 MODULE_LICENSE("GPL v2");