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