Skip to content

Commit f2a22e1

Browse files
biabeniaminjic23
authored andcommitted
iio: adc: ad7606: Add support for software mode for ad7616
Support for ad7616 running in software was added. In order to activate the software mode, HW_RNGSEL pins must be pulled low. Oversampling and input ranges are now configured in corresponding registers. Ad7616 has multiple scale options when it is configured in software mode. Also, in order to support multiple devices in software mode, the spi calculation of registers address must be generic. Because the length of address and bit which specifies the read/write operation is different for every device, calculation of address was made generic. Signed-off-by: Beniamin Bia <beniamin.bia@analog.com> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
1 parent c5d9313 commit f2a22e1

File tree

3 files changed

+213
-9
lines changed

3 files changed

+213
-9
lines changed

drivers/iio/adc/ad7606.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ static const unsigned int ad7606_scale_avail[2] = {
3535
152588, 305176
3636
};
3737

38+
39+
static const unsigned int ad7616_sw_scale_avail[3] = {
40+
76293, 152588, 305176
41+
};
42+
3843
static const unsigned int ad7606_oversampling_avail[7] = {
3944
1, 2, 4, 8, 16, 32, 64,
4045
};
@@ -606,6 +611,10 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address,
606611
"adi,sw-mode");
607612

608613
if (st->sw_mode_en) {
614+
/* Scale of 0.076293 is only available in sw mode */
615+
st->scale_avail = ad7616_sw_scale_avail;
616+
st->num_scales = ARRAY_SIZE(ad7616_sw_scale_avail);
617+
609618
/* After reset, in software mode, ±10 V is set by default */
610619
memset32(st->range, 2, ARRAY_SIZE(st->range));
611620
indio_dev->info = &ad7606_info_os_and_range;

drivers/iio/adc/ad7606.h

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@
88
#ifndef IIO_ADC_AD7606_H_
99
#define IIO_ADC_AD7606_H_
1010

11-
#define AD760X_CHANNEL(num, mask) { \
11+
#define AD760X_CHANNEL(num, mask_sep, mask_type, mask_all) { \
1212
.type = IIO_VOLTAGE, \
1313
.indexed = 1, \
1414
.channel = num, \
1515
.address = num, \
16-
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
17-
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),\
18-
.info_mask_shared_by_all = mask, \
16+
.info_mask_separate = mask_sep, \
17+
.info_mask_shared_by_type = mask_type, \
18+
.info_mask_shared_by_all = mask_all, \
1919
.scan_index = num, \
2020
.scan_type = { \
2121
.sign = 's', \
@@ -25,11 +25,18 @@
2525
}, \
2626
}
2727

28-
#define AD7605_CHANNEL(num) \
29-
AD760X_CHANNEL(num, 0)
28+
#define AD7605_CHANNEL(num) \
29+
AD760X_CHANNEL(num, BIT(IIO_CHAN_INFO_RAW), \
30+
BIT(IIO_CHAN_INFO_SCALE), 0)
3031

31-
#define AD7606_CHANNEL(num) \
32-
AD760X_CHANNEL(num, BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO))
32+
#define AD7606_CHANNEL(num) \
33+
AD760X_CHANNEL(num, BIT(IIO_CHAN_INFO_RAW), \
34+
BIT(IIO_CHAN_INFO_SCALE), \
35+
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO))
36+
37+
#define AD7616_CHANNEL(num) \
38+
AD760X_CHANNEL(num, BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),\
39+
0, BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO))
3340

3441
/**
3542
* struct ad7606_chip_info - chip specific information
@@ -77,6 +84,7 @@ struct ad7606_chip_info {
7784
* @complete completion to indicate end of conversion
7885
* @trig The IIO trigger associated with the device.
7986
* @data buffer for reading data from the device
87+
* @d16 be16 buffer for reading data from the device
8088
*/
8189
struct ad7606_state {
8290
struct device *dev;
@@ -110,18 +118,32 @@ struct ad7606_state {
110118
* 16 * 16-bit samples + 64-bit timestamp
111119
*/
112120
unsigned short data[20] ____cacheline_aligned;
121+
__be16 d16[2];
113122
};
114123

115124
/**
116125
* struct ad7606_bus_ops - driver bus operations
117126
* @read_block function pointer for reading blocks of data
118127
* @sw_mode_config: pointer to a function which configured the device
119128
* for software mode
129+
* @reg_read function pointer for reading spi register
130+
* @reg_write function pointer for writing spi register
131+
* @write_mask function pointer for write spi register with mask
132+
* @rd_wr_cmd pointer to the function which calculates the spi address
120133
*/
121134
struct ad7606_bus_ops {
122135
/* more methods added in future? */
123136
int (*read_block)(struct device *dev, int num, void *data);
124137
int (*sw_mode_config)(struct iio_dev *indio_dev);
138+
int (*reg_read)(struct ad7606_state *st, unsigned int addr);
139+
int (*reg_write)(struct ad7606_state *st,
140+
unsigned int addr,
141+
unsigned int val);
142+
int (*write_mask)(struct ad7606_state *st,
143+
unsigned int addr,
144+
unsigned long mask,
145+
unsigned int val);
146+
u16 (*rd_wr_cmd)(int addr, char isWriteOp);
125147
};
126148

127149
int ad7606_probe(struct device *dev, int irq, void __iomem *base_address,

drivers/iio/adc/ad7606_spi.c

Lines changed: 174 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,51 @@
1515

1616
#define MAX_SPI_FREQ_HZ 23500000 /* VDRIVE above 4.75 V */
1717

18+
#define AD7616_CONFIGURATION_REGISTER 0x02
19+
#define AD7616_OS_MASK GENMASK(4, 2)
20+
#define AD7616_BURST_MODE BIT(6)
21+
#define AD7616_SEQEN_MODE BIT(5)
22+
#define AD7616_RANGE_CH_A_ADDR_OFF 0x04
23+
#define AD7616_RANGE_CH_B_ADDR_OFF 0x06
24+
/*
25+
* Range of channels from a group are stored in 2 registers.
26+
* 0, 1, 2, 3 in a register followed by 4, 5, 6, 7 in second register.
27+
* For channels from second group(8-15) the order is the same, only with
28+
* an offset of 2 for register address.
29+
*/
30+
#define AD7616_RANGE_CH_ADDR(ch) ((ch) >> 2)
31+
/* The range of the channel is stored on 2 bits*/
32+
#define AD7616_RANGE_CH_MSK(ch) (0b11 << (((ch) & 0b11) * 2))
33+
#define AD7616_RANGE_CH_MODE(ch, mode) ((mode) << ((((ch) & 0b11)) * 2))
34+
static const struct iio_chan_spec ad7616_sw_channels[] = {
35+
IIO_CHAN_SOFT_TIMESTAMP(16),
36+
AD7616_CHANNEL(0),
37+
AD7616_CHANNEL(1),
38+
AD7616_CHANNEL(2),
39+
AD7616_CHANNEL(3),
40+
AD7616_CHANNEL(4),
41+
AD7616_CHANNEL(5),
42+
AD7616_CHANNEL(6),
43+
AD7616_CHANNEL(7),
44+
AD7616_CHANNEL(8),
45+
AD7616_CHANNEL(9),
46+
AD7616_CHANNEL(10),
47+
AD7616_CHANNEL(11),
48+
AD7616_CHANNEL(12),
49+
AD7616_CHANNEL(13),
50+
AD7616_CHANNEL(14),
51+
AD7616_CHANNEL(15),
52+
};
53+
54+
static u16 ad7616_spi_rd_wr_cmd(int addr, char isWriteOp)
55+
{
56+
/*
57+
* The address of register consist of one w/r bit
58+
* 6 bits of address followed by one reserved bit.
59+
*/
60+
return ((addr & 0x7F) << 1) | ((isWriteOp & 0x1) << 7);
61+
}
62+
1863
static int ad7606_spi_read_block(struct device *dev,
1964
int count, void *buf)
2065
{
@@ -35,17 +80,145 @@ static int ad7606_spi_read_block(struct device *dev,
3580
return 0;
3681
}
3782

83+
static int ad7606_spi_reg_read(struct ad7606_state *st, unsigned int addr)
84+
{
85+
struct spi_device *spi = to_spi_device(st->dev);
86+
struct spi_transfer t[] = {
87+
{
88+
.tx_buf = &st->d16[0],
89+
.len = 2,
90+
.cs_change = 0,
91+
}, {
92+
.rx_buf = &st->d16[1],
93+
.len = 2,
94+
},
95+
};
96+
int ret;
97+
98+
st->d16[0] = cpu_to_be16(st->bops->rd_wr_cmd(addr, 0) << 8);
99+
100+
ret = spi_sync_transfer(spi, t, ARRAY_SIZE(t));
101+
if (ret < 0)
102+
return ret;
103+
104+
return be16_to_cpu(st->d16[1]);
105+
}
106+
107+
static int ad7606_spi_reg_write(struct ad7606_state *st,
108+
unsigned int addr,
109+
unsigned int val)
110+
{
111+
struct spi_device *spi = to_spi_device(st->dev);
112+
113+
st->d16[0] = cpu_to_be16((st->bops->rd_wr_cmd(addr, 1) << 8) |
114+
(val & 0x1FF));
115+
116+
return spi_write(spi, &st->d16[0], sizeof(st->d16[0]));
117+
}
118+
119+
static int ad7606_spi_write_mask(struct ad7606_state *st,
120+
unsigned int addr,
121+
unsigned long mask,
122+
unsigned int val)
123+
{
124+
int readval;
125+
126+
readval = st->bops->reg_read(st, addr);
127+
if (readval < 0)
128+
return readval;
129+
130+
readval &= ~mask;
131+
readval |= val;
132+
133+
return st->bops->reg_write(st, addr, readval);
134+
}
135+
136+
static int ad7616_write_scale_sw(struct iio_dev *indio_dev, int ch, int val)
137+
{
138+
struct ad7606_state *st = iio_priv(indio_dev);
139+
unsigned int ch_addr, mode, ch_index;
140+
141+
142+
/*
143+
* Ad7616 has 16 channels divided in group A and group B.
144+
* The range of channels from A are stored in registers with address 4
145+
* while channels from B are stored in register with address 6.
146+
* The last bit from channels determines if it is from group A or B
147+
* because the order of channels in iio is 0A, 0B, 1A, 1B...
148+
*/
149+
ch_index = ch >> 1;
150+
151+
ch_addr = AD7616_RANGE_CH_ADDR(ch_index);
152+
153+
if ((ch & 0x1) == 0) /* channel A */
154+
ch_addr += AD7616_RANGE_CH_A_ADDR_OFF;
155+
else /* channel B */
156+
ch_addr += AD7616_RANGE_CH_B_ADDR_OFF;
157+
158+
/* 0b01 for 2.5v, 0b10 for 5v and 0b11 for 10v */
159+
mode = AD7616_RANGE_CH_MODE(ch_index, ((val + 1) & 0b11));
160+
return st->bops->write_mask(st, ch_addr, AD7616_RANGE_CH_MSK(ch_index),
161+
mode);
162+
}
163+
164+
static int ad7616_write_os_sw(struct iio_dev *indio_dev, int val)
165+
{
166+
struct ad7606_state *st = iio_priv(indio_dev);
167+
168+
return st->bops->write_mask(st, AD7616_CONFIGURATION_REGISTER,
169+
AD7616_OS_MASK, val << 2);
170+
}
171+
172+
static int ad7616_sw_mode_config(struct iio_dev *indio_dev)
173+
{
174+
struct ad7606_state *st = iio_priv(indio_dev);
175+
176+
/*
177+
* Scale can be configured individually for each channel
178+
* in software mode.
179+
*/
180+
indio_dev->channels = ad7616_sw_channels;
181+
182+
st->write_scale = ad7616_write_scale_sw;
183+
st->write_os = &ad7616_write_os_sw;
184+
185+
/* Activate Burst mode and SEQEN MODE */
186+
return st->bops->write_mask(st,
187+
AD7616_CONFIGURATION_REGISTER,
188+
AD7616_BURST_MODE | AD7616_SEQEN_MODE,
189+
AD7616_BURST_MODE | AD7616_SEQEN_MODE);
190+
}
191+
38192
static const struct ad7606_bus_ops ad7606_spi_bops = {
39193
.read_block = ad7606_spi_read_block,
40194
};
41195

196+
static const struct ad7606_bus_ops ad7616_spi_bops = {
197+
.read_block = ad7606_spi_read_block,
198+
.reg_read = ad7606_spi_reg_read,
199+
.reg_write = ad7606_spi_reg_write,
200+
.write_mask = ad7606_spi_write_mask,
201+
.rd_wr_cmd = ad7616_spi_rd_wr_cmd,
202+
.sw_mode_config = ad7616_sw_mode_config,
203+
};
204+
42205
static int ad7606_spi_probe(struct spi_device *spi)
43206
{
44207
const struct spi_device_id *id = spi_get_device_id(spi);
208+
const struct ad7606_bus_ops *bops;
209+
210+
switch (id->driver_data) {
211+
case ID_AD7616:
212+
bops = &ad7616_spi_bops;
213+
break;
214+
default:
215+
bops = &ad7606_spi_bops;
216+
break;
217+
}
45218

46219
return ad7606_probe(&spi->dev, spi->irq, NULL,
47220
id->name, id->driver_data,
48-
&ad7606_spi_bops);
221+
bops);
49222
}
50223

51224
static const struct spi_device_id ad7606_id_table[] = {

0 commit comments

Comments
 (0)