Skip to content

Commit 11ab555

Browse files
commodojic23
authored andcommitted
iio: amplifiers: ad8366: rework driver to allow other chips
The SPI gain amplifiers are simple devices, with 1 or 2 channels, to which are read-from/written-to. The gain computation in ad8366_write_raw() has been updated to compute gain in dB for negative values. This driver will be extended to support other chips as well. To do that, this rework handles the AD8366 device as a special-case (via switch-statements). This will make things easier when adding new chips. Signed-off-by: Alexandru Ardelean <[email protected]> Signed-off-by: Jonathan Cameron <[email protected]>
1 parent dbcf6b5 commit 11ab555

File tree

1 file changed

+62
-19
lines changed

1 file changed

+62
-19
lines changed

drivers/iio/amplifiers/ad8366.c

Lines changed: 62 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,31 +18,53 @@
1818
#include <linux/iio/iio.h>
1919
#include <linux/iio/sysfs.h>
2020

21+
enum ad8366_type {
22+
ID_AD8366,
23+
};
24+
25+
struct ad8366_info {
26+
int gain_min;
27+
int gain_max;
28+
};
29+
2130
struct ad8366_state {
2231
struct spi_device *spi;
2332
struct regulator *reg;
2433
struct mutex lock; /* protect sensor state */
2534
unsigned char ch[2];
35+
enum ad8366_type type;
36+
struct ad8366_info *info;
2637
/*
2738
* DMA (thus cache coherency maintenance) requires the
2839
* transfer buffers to live in their own cache lines.
2940
*/
3041
unsigned char data[2] ____cacheline_aligned;
3142
};
3243

44+
static struct ad8366_info ad8366_infos[] = {
45+
[ID_AD8366] = {
46+
.gain_min = 4500,
47+
.gain_max = 20500,
48+
},
49+
};
50+
3351
static int ad8366_write(struct iio_dev *indio_dev,
3452
unsigned char ch_a, unsigned char ch_b)
3553
{
3654
struct ad8366_state *st = iio_priv(indio_dev);
3755
int ret;
3856

39-
ch_a = bitrev8(ch_a & 0x3F);
40-
ch_b = bitrev8(ch_b & 0x3F);
57+
switch (st->type) {
58+
case ID_AD8366:
59+
ch_a = bitrev8(ch_a & 0x3F);
60+
ch_b = bitrev8(ch_b & 0x3F);
4161

42-
st->data[0] = ch_b >> 4;
43-
st->data[1] = (ch_b << 4) | (ch_a >> 2);
62+
st->data[0] = ch_b >> 4;
63+
st->data[1] = (ch_b << 4) | (ch_a >> 2);
64+
break;
65+
}
4466

45-
ret = spi_write(st->spi, st->data, ARRAY_SIZE(st->data));
67+
ret = spi_write(st->spi, st->data, indio_dev->num_channels);
4668
if (ret < 0)
4769
dev_err(&indio_dev->dev, "write failed (%d)", ret);
4870

@@ -57,17 +79,22 @@ static int ad8366_read_raw(struct iio_dev *indio_dev,
5779
{
5880
struct ad8366_state *st = iio_priv(indio_dev);
5981
int ret;
60-
unsigned code;
82+
int code, gain = 0;
6183

6284
mutex_lock(&st->lock);
6385
switch (m) {
6486
case IIO_CHAN_INFO_HARDWAREGAIN:
6587
code = st->ch[chan->channel];
6688

89+
switch (st->type) {
90+
case ID_AD8366:
91+
gain = code * 253 + 4500;
92+
break;
93+
}
94+
6795
/* Values in dB */
68-
code = code * 253 + 4500;
69-
*val = code / 1000;
70-
*val2 = (code % 1000) * 1000;
96+
*val = gain / 1000;
97+
*val2 = (gain % 1000) * 1000;
7198

7299
ret = IIO_VAL_INT_PLUS_MICRO_DB;
73100
break;
@@ -86,19 +113,24 @@ static int ad8366_write_raw(struct iio_dev *indio_dev,
86113
long mask)
87114
{
88115
struct ad8366_state *st = iio_priv(indio_dev);
89-
unsigned code;
116+
struct ad8366_info *inf = st->info;
117+
int code = 0, gain;
90118
int ret;
91119

92-
if (val < 0 || val2 < 0)
93-
return -EINVAL;
94-
95120
/* Values in dB */
96-
code = (((u8)val * 1000) + ((u32)val2 / 1000));
121+
if (val < 0)
122+
gain = (val * 1000) - (val2 / 1000);
123+
else
124+
gain = (val * 1000) + (val2 / 1000);
97125

98-
if (code > 20500 || code < 4500)
126+
if (gain > inf->gain_max || gain < inf->gain_min)
99127
return -EINVAL;
100128

101-
code = (code - 4500) / 253;
129+
switch (st->type) {
130+
case ID_AD8366:
131+
code = (gain - 4500) / 253;
132+
break;
133+
}
102134

103135
mutex_lock(&st->lock);
104136
switch (mask) {
@@ -154,13 +186,24 @@ static int ad8366_probe(struct spi_device *spi)
154186
spi_set_drvdata(spi, indio_dev);
155187
mutex_init(&st->lock);
156188
st->spi = spi;
189+
st->type = spi_get_device_id(spi)->driver_data;
190+
191+
switch (st->type) {
192+
case ID_AD8366:
193+
indio_dev->channels = ad8366_channels;
194+
indio_dev->num_channels = ARRAY_SIZE(ad8366_channels);
195+
break;
196+
default:
197+
dev_err(&spi->dev, "Invalid device ID\n");
198+
ret = -EINVAL;
199+
goto error_disable_reg;
200+
}
157201

202+
st->info = &ad8366_infos[st->type];
158203
indio_dev->dev.parent = &spi->dev;
159204
indio_dev->name = spi_get_device_id(spi)->name;
160205
indio_dev->info = &ad8366_info;
161206
indio_dev->modes = INDIO_DIRECT_MODE;
162-
indio_dev->channels = ad8366_channels;
163-
indio_dev->num_channels = ARRAY_SIZE(ad8366_channels);
164207

165208
ret = ad8366_write(indio_dev, 0 , 0);
166209
if (ret < 0)
@@ -194,7 +237,7 @@ static int ad8366_remove(struct spi_device *spi)
194237
}
195238

196239
static const struct spi_device_id ad8366_id[] = {
197-
{"ad8366", 0},
240+
{"ad8366", ID_AD8366},
198241
{}
199242
};
200243
MODULE_DEVICE_TABLE(spi, ad8366_id);

0 commit comments

Comments
 (0)