xref: /linux/drivers/iio/amplifiers/ad8366.c (revision cb4eb6771c0f8fd1c52a8f6fdec7762fb087380a)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * AD8366 and similar Gain Amplifiers
4  * This driver supports the following gain amplifiers:
5  *   AD8366 Dual-Digital Variable Gain Amplifier (VGA)
6  *   ADA4961 BiCMOS RF Digital Gain Amplifier (DGA)
7  *   ADL5240 Digitally controlled variable gain amplifier (VGA)
8  *   ADRF5702: 0.125 dB LSB, 8-Bit, Silicon Digital Attenuator, 50 MHz to 20 GHz
9  *   ADRF5703: 0.25 dB LSB, 7-Bit, Silicon Digital Attenuator, 9 kHz to 20 GHz
10  *   ADRF5720: 0.5 dB LSB, 6-Bit, Silicon Digital Attenuator, 9 kHz to 40 GHz
11  *   ADRF5730: 0.5 dB LSB, 6-Bit, Silicon Digital Attenuator, 100 MHz to 40 GHz
12  *   ADRF5731: 2 dB LSB, 4-Bit, Silicon Digital Attenuator, 100 MHz to 40 GHz
13  *   HMC271A: 1dB LSB 5-Bit Digital Attenuator SMT, 0.7 - 3.7 GHz
14  *   HMC792A 0.25 dB LSB GaAs MMIC 6-Bit Digital Attenuator
15  *   HMC1018A: 1.0 dB LSB GaAs MMIC 5-BIT DIGITAL ATTENUATOR, 0.1 - 30 GHz
16  *   HMC1019A: 0.5 dB LSB GaAs MMIC 5-BIT DIGITAL ATTENUATOR, 0.1 - 30 GHz
17  *   HMC1119 0.25 dB LSB, 7-Bit, Silicon Digital Attenuator
18  *
19  * Copyright 2012-2026 Analog Devices Inc.
20  */
21 
22 #include <linux/bitrev.h>
23 #include <linux/bits.h>
24 #include <linux/dev_printk.h>
25 #include <linux/err.h>
26 #include <linux/gpio/consumer.h>
27 #include <linux/math.h>
28 #include <linux/minmax.h>
29 #include <linux/mod_devicetable.h>
30 #include <linux/module.h>
31 #include <linux/mutex.h>
32 #include <linux/regulator/consumer.h>
33 #include <linux/reset.h>
34 #include <linux/spi/spi.h>
35 #include <linux/types.h>
36 #include <linux/unaligned.h>
37 
38 #include <linux/iio/iio.h>
39 
40 struct ad8366_info {
41 	const char *name;
42 	int gain_min;
43 	int gain_max;
44 	int gain_step;
45 	size_t num_channels;
46 	size_t (*pack_code)(const unsigned char *code, size_t num_channels,
47 			    unsigned char *data);
48 };
49 
50 struct ad8366_state {
51 	struct spi_device	*spi;
52 	struct mutex            lock; /* protect sensor state */
53 	unsigned char		ch[2];
54 	const struct ad8366_info *info;
55 	/*
56 	 * DMA (thus cache coherency maintenance) may require the
57 	 * transfer buffers to live in their own cache lines.
58 	 */
59 	unsigned char		data[2] __aligned(IIO_DMA_MINALIGN);
60 };
61 
ad8366_pack_code(const unsigned char * code,size_t num_channels,unsigned char * data)62 static size_t ad8366_pack_code(const unsigned char *code, size_t num_channels,
63 			       unsigned char *data)
64 {
65 	u8 ch_a = bitrev8(code[0]) >> 2;
66 	u8 ch_b = bitrev8(code[1]) >> 2;
67 
68 	put_unaligned_be16((ch_b << 6) | ch_a, &data[0]);
69 	return sizeof(__be16);
70 }
71 
adrf5731_pack_code(const unsigned char * code,size_t num_channels,unsigned char * data)72 static size_t adrf5731_pack_code(const unsigned char *code, size_t num_channels,
73 				 unsigned char *data)
74 {
75 	data[0] = code[0] << 2;
76 	return 1;
77 }
78 
hmc271_pack_code(const unsigned char * code,size_t num_channels,unsigned char * data)79 static size_t hmc271_pack_code(const unsigned char *code, size_t num_channels,
80 			       unsigned char *data)
81 {
82 	data[0] = bitrev8(code[0]) >> 3;
83 	return 1;
84 }
85 
86 static const struct ad8366_info ad8366_chip_info = {
87 	.name = "ad8366",
88 	.gain_min = 4500,
89 	.gain_max = 20500,
90 	.gain_step = 253,
91 	.num_channels = 2,
92 	.pack_code = ad8366_pack_code,
93 };
94 
95 static const struct ad8366_info ada4961_chip_info = {
96 	.name = "ada4961",
97 	.gain_min = -6000,
98 	.gain_max = 15000,
99 	.gain_step = -1000,
100 	.num_channels = 1,
101 };
102 
103 static const struct ad8366_info adl5240_chip_info = {
104 	.name = "adl5240",
105 	.gain_min = -11500,
106 	.gain_max = 20000,
107 	.gain_step = 500,
108 	.num_channels = 1,
109 };
110 
111 static const struct ad8366_info adrf5702_chip_info = {
112 	.name = "adrf5702",
113 	.gain_min = -31875,
114 	.gain_max = 0,
115 	.gain_step = -125,
116 	.num_channels = 1,
117 };
118 
119 static const struct ad8366_info adrf5703_chip_info = {
120 	.name = "adrf5703",
121 	.gain_min = -31750,
122 	.gain_max = 0,
123 	.gain_step = -250,
124 	.num_channels = 1,
125 };
126 
127 static const struct ad8366_info adrf5720_chip_info = {
128 	.name = "adrf5720",
129 	.gain_min = -31500,
130 	.gain_max = 0,
131 	.gain_step = -500,
132 	.num_channels = 1,
133 };
134 
135 static const struct ad8366_info adrf5730_chip_info = {
136 	.name = "adrf5730",
137 	.gain_min = -31500,
138 	.gain_max = 0,
139 	.gain_step = -500,
140 	.num_channels = 1,
141 };
142 
143 static const struct ad8366_info adrf5731_chip_info = {
144 	.name = "adrf5731",
145 	.gain_min = -30000,
146 	.gain_max = 0,
147 	.gain_step = -2000,
148 	.num_channels = 1,
149 	.pack_code = adrf5731_pack_code,
150 };
151 
152 static const struct ad8366_info hmc271_chip_info = {
153 	.name = "hmc271a",
154 	.gain_min = -31000,
155 	.gain_max = 0,
156 	.gain_step = 1000,
157 	.num_channels = 1,
158 	.pack_code = hmc271_pack_code,
159 };
160 
161 static const struct ad8366_info hmc792_chip_info = {
162 	.name = "hmc792a",
163 	.gain_min = -15750,
164 	.gain_max = 0,
165 	.gain_step = 250,
166 	.num_channels = 1,
167 };
168 
169 static const struct ad8366_info hmc1018_chip_info = {
170 	.name = "hmc1018a",
171 	.gain_min = -31000,
172 	.gain_max = 0,
173 	.gain_step = 1000,
174 	.num_channels = 1,
175 };
176 
177 static const struct ad8366_info hmc1019_chip_info = {
178 	.name = "hmc1019a",
179 	.gain_min = -15500,
180 	.gain_max = 0,
181 	.gain_step = 500,
182 	.num_channels = 1,
183 };
184 
185 static const struct ad8366_info hmc1119_chip_info = {
186 	.name = "hmc1119",
187 	.gain_min = -31750,
188 	.gain_max = 0,
189 	.gain_step = -250,
190 	.num_channels = 1,
191 };
192 
ad8366_write_code(struct ad8366_state * st)193 static int ad8366_write_code(struct ad8366_state *st)
194 {
195 	const struct ad8366_info *inf = st->info;
196 	size_t len = 1;
197 
198 	if (inf->pack_code)
199 		len = inf->pack_code(st->ch, inf->num_channels, st->data);
200 	else
201 		st->data[0] = st->ch[0];
202 
203 	return spi_write(st->spi, st->data, len);
204 }
205 
ad8366_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long m)206 static int ad8366_read_raw(struct iio_dev *indio_dev,
207 			   struct iio_chan_spec const *chan,
208 			   int *val,
209 			   int *val2,
210 			   long m)
211 {
212 	struct ad8366_state *st = iio_priv(indio_dev);
213 	const struct ad8366_info *inf = st->info;
214 	int ret;
215 	int code, gain = 0;
216 
217 	mutex_lock(&st->lock);
218 	switch (m) {
219 	case IIO_CHAN_INFO_HARDWAREGAIN:
220 		code = st->ch[chan->channel];
221 		gain = inf->gain_step > 0 ? inf->gain_min : inf->gain_max;
222 		gain += inf->gain_step * code;
223 		/* Values in dB */
224 		*val = gain / 1000;
225 		*val2 = (gain % 1000) * 1000;
226 
227 		ret = IIO_VAL_INT_PLUS_MICRO_DB;
228 		break;
229 	default:
230 		ret = -EINVAL;
231 	}
232 	mutex_unlock(&st->lock);
233 
234 	return ret;
235 };
236 
ad8366_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int val,int val2,long mask)237 static int ad8366_write_raw(struct iio_dev *indio_dev,
238 			    struct iio_chan_spec const *chan,
239 			    int val,
240 			    int val2,
241 			    long mask)
242 {
243 	struct ad8366_state *st = iio_priv(indio_dev);
244 	const struct ad8366_info *inf = st->info;
245 	int code = 0, gain;
246 	int ret;
247 
248 	/* Values in dB */
249 	if (val < 0)
250 		gain = (val * 1000) - (val2 / 1000);
251 	else
252 		gain = (val * 1000) + (val2 / 1000);
253 
254 	if (gain > inf->gain_max || gain < inf->gain_min)
255 		return -EINVAL;
256 
257 	gain -= inf->gain_step > 0 ? inf->gain_min : inf->gain_max;
258 	code = DIV_ROUND_CLOSEST(gain, inf->gain_step);
259 
260 	mutex_lock(&st->lock);
261 	switch (mask) {
262 	case IIO_CHAN_INFO_HARDWAREGAIN:
263 		st->ch[chan->channel] = code;
264 		ret = ad8366_write_code(st);
265 		break;
266 	default:
267 		ret = -EINVAL;
268 	}
269 	mutex_unlock(&st->lock);
270 
271 	return ret;
272 }
273 
ad8366_write_raw_get_fmt(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,long mask)274 static int ad8366_write_raw_get_fmt(struct iio_dev *indio_dev,
275 				    struct iio_chan_spec const *chan,
276 				    long mask)
277 {
278 	switch (mask) {
279 	case IIO_CHAN_INFO_HARDWAREGAIN:
280 		return IIO_VAL_INT_PLUS_MICRO_DB;
281 	default:
282 		return -EINVAL;
283 	}
284 }
285 
286 static const struct iio_info ad8366_info = {
287 	.read_raw = &ad8366_read_raw,
288 	.write_raw = &ad8366_write_raw,
289 	.write_raw_get_fmt = &ad8366_write_raw_get_fmt,
290 };
291 
292 #define AD8366_CHAN(_channel) {				\
293 	.type = IIO_VOLTAGE,				\
294 	.output = 1,					\
295 	.indexed = 1,					\
296 	.channel = _channel,				\
297 	.info_mask_separate = BIT(IIO_CHAN_INFO_HARDWAREGAIN),\
298 }
299 
300 static const struct iio_chan_spec ad8366_channels[] = {
301 	AD8366_CHAN(0),
302 	AD8366_CHAN(1),
303 };
304 
ad8366_probe(struct spi_device * spi)305 static int ad8366_probe(struct spi_device *spi)
306 {
307 	struct device *dev = &spi->dev;
308 	struct gpio_desc *enable_gpio;
309 	struct reset_control *rstc;
310 	struct iio_dev *indio_dev;
311 	struct ad8366_state *st;
312 	int ret;
313 
314 	indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
315 	if (indio_dev == NULL)
316 		return -ENOMEM;
317 
318 	st = iio_priv(indio_dev);
319 
320 	ret = devm_mutex_init(dev, &st->lock);
321 	if (ret)
322 		return ret;
323 
324 	ret = devm_regulator_get_enable(dev, "vcc");
325 	if (ret)
326 		return dev_err_probe(dev, ret, "Failed to get regulator\n");
327 
328 	st->spi = spi;
329 	st->info = spi_get_device_match_data(spi);
330 
331 	enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_HIGH);
332 	if (IS_ERR(enable_gpio))
333 		return dev_err_probe(dev, PTR_ERR(enable_gpio),
334 				     "Failed to get enable GPIO\n");
335 
336 	rstc = devm_reset_control_get_optional_exclusive_deasserted(dev, NULL);
337 	if (IS_ERR(rstc))
338 		return dev_err_probe(dev, PTR_ERR(rstc),
339 				     "Failed to get reset controller\n");
340 
341 	indio_dev->name = st->info->name;
342 	indio_dev->info = &ad8366_info;
343 	indio_dev->modes = INDIO_DIRECT_MODE;
344 	indio_dev->channels = ad8366_channels;
345 	indio_dev->num_channels = st->info->num_channels;
346 
347 	ret = ad8366_write_code(st);
348 	if (ret < 0)
349 		return dev_err_probe(dev, ret, "failed to write initial gain\n");
350 
351 	return devm_iio_device_register(dev, indio_dev);
352 }
353 
354 static const struct spi_device_id ad8366_id[] = {
355 	{ "ad8366", (kernel_ulong_t)&ad8366_chip_info },
356 	{ "ada4961", (kernel_ulong_t)&ada4961_chip_info },
357 	{ "adl5240", (kernel_ulong_t)&adl5240_chip_info },
358 	{ "adrf5702", (kernel_ulong_t)&adrf5702_chip_info },
359 	{ "adrf5703", (kernel_ulong_t)&adrf5703_chip_info },
360 	{ "adrf5720", (kernel_ulong_t)&adrf5720_chip_info },
361 	{ "adrf5730", (kernel_ulong_t)&adrf5730_chip_info },
362 	{ "adrf5731", (kernel_ulong_t)&adrf5731_chip_info },
363 	{ "hmc271a", (kernel_ulong_t)&hmc271_chip_info },
364 	{ "hmc792a", (kernel_ulong_t)&hmc792_chip_info },
365 	{ "hmc1018a", (kernel_ulong_t)&hmc1018_chip_info },
366 	{ "hmc1019a", (kernel_ulong_t)&hmc1019_chip_info },
367 	{ "hmc1119", (kernel_ulong_t)&hmc1119_chip_info },
368 	{ }
369 };
370 MODULE_DEVICE_TABLE(spi, ad8366_id);
371 
372 static const struct of_device_id ad8366_of_match[] = {
373 	{ .compatible = "adi,ad8366", .data = &ad8366_chip_info },
374 	{ .compatible = "adi,ada4961", .data = &ada4961_chip_info },
375 	{ .compatible = "adi,adl5240", .data = &adl5240_chip_info },
376 	{ .compatible = "adi,adrf5702", .data = &adrf5702_chip_info },
377 	{ .compatible = "adi,adrf5703", .data = &adrf5703_chip_info },
378 	{ .compatible = "adi,adrf5720", .data = &adrf5720_chip_info },
379 	{ .compatible = "adi,adrf5730", .data = &adrf5730_chip_info },
380 	{ .compatible = "adi,adrf5731", .data = &adrf5731_chip_info },
381 	{ .compatible = "adi,hmc271a", .data = &hmc271_chip_info },
382 	{ .compatible = "adi,hmc792a", .data = &hmc792_chip_info },
383 	{ .compatible = "adi,hmc1018a", .data = &hmc1018_chip_info },
384 	{ .compatible = "adi,hmc1019a", .data = &hmc1019_chip_info },
385 	{ .compatible = "adi,hmc1119", .data = &hmc1119_chip_info },
386 	{ }
387 };
388 MODULE_DEVICE_TABLE(of, ad8366_of_match);
389 
390 static struct spi_driver ad8366_driver = {
391 	.driver = {
392 		.name		= KBUILD_MODNAME,
393 		.of_match_table	= ad8366_of_match,
394 	},
395 	.probe		= ad8366_probe,
396 	.id_table	= ad8366_id,
397 };
398 
399 module_spi_driver(ad8366_driver);
400 
401 MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
402 MODULE_DESCRIPTION("Analog Devices AD8366 and similar Gain Amplifiers");
403 MODULE_LICENSE("GPL v2");
404