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