hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/drivers/iio/amplifiers/ad8366.c
....@@ -1,9 +1,13 @@
1
+// SPDX-License-Identifier: GPL-2.0
12 /*
2
- * AD8366 SPI Dual-Digital Variable Gain Amplifier (VGA)
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
+ * HMC1119 0.25 dB LSB, 7-Bit, Silicon Digital Attenuator
39 *
4
- * Copyright 2012 Analog Devices Inc.
5
- *
6
- * Licensed under the GPL-2.
10
+ * Copyright 2012-2019 Analog Devices Inc.
711 */
812
913 #include <linux/device.h>
....@@ -12,6 +16,7 @@
1216 #include <linux/sysfs.h>
1317 #include <linux/spi/spi.h>
1418 #include <linux/regulator/consumer.h>
19
+#include <linux/gpio/consumer.h>
1520 #include <linux/err.h>
1621 #include <linux/module.h>
1722 #include <linux/bitrev.h>
....@@ -19,15 +24,50 @@
1924 #include <linux/iio/iio.h>
2025 #include <linux/iio/sysfs.h>
2126
27
+enum ad8366_type {
28
+ ID_AD8366,
29
+ ID_ADA4961,
30
+ ID_ADL5240,
31
+ ID_HMC1119,
32
+};
33
+
34
+struct ad8366_info {
35
+ int gain_min;
36
+ int gain_max;
37
+};
38
+
2239 struct ad8366_state {
2340 struct spi_device *spi;
2441 struct regulator *reg;
42
+ struct mutex lock; /* protect sensor state */
43
+ struct gpio_desc *reset_gpio;
2544 unsigned char ch[2];
45
+ enum ad8366_type type;
46
+ struct ad8366_info *info;
2647 /*
2748 * DMA (thus cache coherency maintenance) requires the
2849 * transfer buffers to live in their own cache lines.
2950 */
3051 unsigned char data[2] ____cacheline_aligned;
52
+};
53
+
54
+static struct ad8366_info ad8366_infos[] = {
55
+ [ID_AD8366] = {
56
+ .gain_min = 4500,
57
+ .gain_max = 20500,
58
+ },
59
+ [ID_ADA4961] = {
60
+ .gain_min = -6000,
61
+ .gain_max = 15000,
62
+ },
63
+ [ID_ADL5240] = {
64
+ .gain_min = -11500,
65
+ .gain_max = 20000,
66
+ },
67
+ [ID_HMC1119] = {
68
+ .gain_min = -31750,
69
+ .gain_max = 0,
70
+ },
3171 };
3272
3373 static int ad8366_write(struct iio_dev *indio_dev,
....@@ -36,13 +76,26 @@
3676 struct ad8366_state *st = iio_priv(indio_dev);
3777 int ret;
3878
39
- ch_a = bitrev8(ch_a & 0x3F);
40
- ch_b = bitrev8(ch_b & 0x3F);
79
+ switch (st->type) {
80
+ case ID_AD8366:
81
+ ch_a = bitrev8(ch_a & 0x3F);
82
+ ch_b = bitrev8(ch_b & 0x3F);
4183
42
- st->data[0] = ch_b >> 4;
43
- st->data[1] = (ch_b << 4) | (ch_a >> 2);
84
+ st->data[0] = ch_b >> 4;
85
+ st->data[1] = (ch_b << 4) | (ch_a >> 2);
86
+ break;
87
+ case ID_ADA4961:
88
+ st->data[0] = ch_a & 0x1F;
89
+ break;
90
+ case ID_ADL5240:
91
+ st->data[0] = (ch_a & 0x3F);
92
+ break;
93
+ case ID_HMC1119:
94
+ st->data[0] = ch_a;
95
+ break;
96
+ }
4497
45
- ret = spi_write(st->spi, st->data, ARRAY_SIZE(st->data));
98
+ ret = spi_write(st->spi, st->data, indio_dev->num_channels);
4699 if (ret < 0)
47100 dev_err(&indio_dev->dev, "write failed (%d)", ret);
48101
....@@ -57,24 +110,38 @@
57110 {
58111 struct ad8366_state *st = iio_priv(indio_dev);
59112 int ret;
60
- unsigned code;
113
+ int code, gain = 0;
61114
62
- mutex_lock(&indio_dev->mlock);
115
+ mutex_lock(&st->lock);
63116 switch (m) {
64117 case IIO_CHAN_INFO_HARDWAREGAIN:
65118 code = st->ch[chan->channel];
66119
120
+ switch (st->type) {
121
+ case ID_AD8366:
122
+ gain = code * 253 + 4500;
123
+ break;
124
+ case ID_ADA4961:
125
+ gain = 15000 - code * 1000;
126
+ break;
127
+ case ID_ADL5240:
128
+ gain = 20000 - 31500 + code * 500;
129
+ break;
130
+ case ID_HMC1119:
131
+ gain = -1 * code * 250;
132
+ break;
133
+ }
134
+
67135 /* Values in dB */
68
- code = code * 253 + 4500;
69
- *val = code / 1000;
70
- *val2 = (code % 1000) * 1000;
136
+ *val = gain / 1000;
137
+ *val2 = (gain % 1000) * 1000;
71138
72139 ret = IIO_VAL_INT_PLUS_MICRO_DB;
73140 break;
74141 default:
75142 ret = -EINVAL;
76143 }
77
- mutex_unlock(&indio_dev->mlock);
144
+ mutex_unlock(&st->lock);
78145
79146 return ret;
80147 };
....@@ -86,21 +153,35 @@
86153 long mask)
87154 {
88155 struct ad8366_state *st = iio_priv(indio_dev);
89
- unsigned code;
156
+ struct ad8366_info *inf = st->info;
157
+ int code = 0, gain;
90158 int ret;
91159
92
- if (val < 0 || val2 < 0)
93
- return -EINVAL;
94
-
95160 /* Values in dB */
96
- code = (((u8)val * 1000) + ((u32)val2 / 1000));
161
+ if (val < 0)
162
+ gain = (val * 1000) - (val2 / 1000);
163
+ else
164
+ gain = (val * 1000) + (val2 / 1000);
97165
98
- if (code > 20500 || code < 4500)
166
+ if (gain > inf->gain_max || gain < inf->gain_min)
99167 return -EINVAL;
100168
101
- code = (code - 4500) / 253;
169
+ switch (st->type) {
170
+ case ID_AD8366:
171
+ code = (gain - 4500) / 253;
172
+ break;
173
+ case ID_ADA4961:
174
+ code = (15000 - gain) / 1000;
175
+ break;
176
+ case ID_ADL5240:
177
+ code = ((gain - 500 - 20000) / 500) & 0x3F;
178
+ break;
179
+ case ID_HMC1119:
180
+ code = (abs(gain) / 250) & 0x7F;
181
+ break;
182
+ }
102183
103
- mutex_lock(&indio_dev->mlock);
184
+ mutex_lock(&st->lock);
104185 switch (mask) {
105186 case IIO_CHAN_INFO_HARDWAREGAIN:
106187 st->ch[chan->channel] = code;
....@@ -109,14 +190,27 @@
109190 default:
110191 ret = -EINVAL;
111192 }
112
- mutex_unlock(&indio_dev->mlock);
193
+ mutex_unlock(&st->lock);
113194
114195 return ret;
196
+}
197
+
198
+static int ad8366_write_raw_get_fmt(struct iio_dev *indio_dev,
199
+ struct iio_chan_spec const *chan,
200
+ long mask)
201
+{
202
+ switch (mask) {
203
+ case IIO_CHAN_INFO_HARDWAREGAIN:
204
+ return IIO_VAL_INT_PLUS_MICRO_DB;
205
+ default:
206
+ return -EINVAL;
207
+ }
115208 }
116209
117210 static const struct iio_info ad8366_info = {
118211 .read_raw = &ad8366_read_raw,
119212 .write_raw = &ad8366_write_raw,
213
+ .write_raw_get_fmt = &ad8366_write_raw_get_fmt,
120214 };
121215
122216 #define AD8366_CHAN(_channel) { \
....@@ -130,6 +224,10 @@
130224 static const struct iio_chan_spec ad8366_channels[] = {
131225 AD8366_CHAN(0),
132226 AD8366_CHAN(1),
227
+};
228
+
229
+static const struct iio_chan_spec ada4961_channels[] = {
230
+ AD8366_CHAN(0),
133231 };
134232
135233 static int ad8366_probe(struct spi_device *spi)
....@@ -152,14 +250,36 @@
152250 }
153251
154252 spi_set_drvdata(spi, indio_dev);
253
+ mutex_init(&st->lock);
155254 st->spi = spi;
255
+ st->type = spi_get_device_id(spi)->driver_data;
156256
157
- indio_dev->dev.parent = &spi->dev;
257
+ switch (st->type) {
258
+ case ID_AD8366:
259
+ indio_dev->channels = ad8366_channels;
260
+ indio_dev->num_channels = ARRAY_SIZE(ad8366_channels);
261
+ break;
262
+ case ID_ADA4961:
263
+ case ID_ADL5240:
264
+ case ID_HMC1119:
265
+ st->reset_gpio = devm_gpiod_get_optional(&spi->dev, "reset", GPIOD_OUT_HIGH);
266
+ if (IS_ERR(st->reset_gpio)) {
267
+ ret = PTR_ERR(st->reset_gpio);
268
+ goto error_disable_reg;
269
+ }
270
+ indio_dev->channels = ada4961_channels;
271
+ indio_dev->num_channels = ARRAY_SIZE(ada4961_channels);
272
+ break;
273
+ default:
274
+ dev_err(&spi->dev, "Invalid device ID\n");
275
+ ret = -EINVAL;
276
+ goto error_disable_reg;
277
+ }
278
+
279
+ st->info = &ad8366_infos[st->type];
158280 indio_dev->name = spi_get_device_id(spi)->name;
159281 indio_dev->info = &ad8366_info;
160282 indio_dev->modes = INDIO_DIRECT_MODE;
161
- indio_dev->channels = ad8366_channels;
162
- indio_dev->num_channels = ARRAY_SIZE(ad8366_channels);
163283
164284 ret = ad8366_write(indio_dev, 0 , 0);
165285 if (ret < 0)
....@@ -193,7 +313,10 @@
193313 }
194314
195315 static const struct spi_device_id ad8366_id[] = {
196
- {"ad8366", 0},
316
+ {"ad8366", ID_AD8366},
317
+ {"ada4961", ID_ADA4961},
318
+ {"adl5240", ID_ADL5240},
319
+ {"hmc1119", ID_HMC1119},
197320 {}
198321 };
199322 MODULE_DEVICE_TABLE(spi, ad8366_id);
....@@ -209,6 +332,6 @@
209332
210333 module_spi_driver(ad8366_driver);
211334
212
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
213
-MODULE_DESCRIPTION("Analog Devices AD8366 VGA");
335
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
336
+MODULE_DESCRIPTION("Analog Devices AD8366 and similar Gain Amplifiers");
214337 MODULE_LICENSE("GPL v2");