Skip to content

Commit 2e1d5e0

Browse files
gstolssmb49
authored andcommitted
iio: adc: ad7606: move software functions into common file
BugLink: https://bugs.launchpad.net/bugs/2115266 [ Upstream commit d2477887f6677de0675e600f1590378a5fb52909 ] Since the register are always the same, whatever bus is used, moving the software functions into the main file avoids the code to be duplicated in both SPI and parallel version of the driver. Signed-off-by: Guillaume Stols <gstols@baylibre.com> Co-developed-by: Angelo Dureghello <adureghello@baylibre.com> Signed-off-by: Angelo Dureghello <adureghello@baylibre.com> Link: https://patch.msgid.link/20250210-wip-bl-ad7606_add_backend_sw_mode-v4-3-160df18b1da7@baylibre.com Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Stable-dep-of: 5257d80e22bf ("iio: adc: ad7606: check for NULL before calling sw_mode_config()") Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Manuel Diewald <manuel.diewald@canonical.com> Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
1 parent 3641b8f commit 2e1d5e0

File tree

3 files changed

+158
-149
lines changed

3 files changed

+158
-149
lines changed

drivers/iio/adc/ad7606.c

Lines changed: 124 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ static const unsigned int ad7606_oversampling_avail[7] = {
8585
1, 2, 4, 8, 16, 32, 64,
8686
};
8787

88+
static const unsigned int ad7606b_oversampling_avail[9] = {
89+
1, 2, 4, 8, 16, 32, 64, 128, 256,
90+
};
91+
8892
static const unsigned int ad7616_oversampling_avail[8] = {
8993
1, 2, 4, 8, 16, 32, 64, 128,
9094
};
@@ -187,6 +191,8 @@ static int ad7608_chan_scale_setup(struct iio_dev *indio_dev,
187191
struct iio_chan_spec *chan, int ch);
188192
static int ad7609_chan_scale_setup(struct iio_dev *indio_dev,
189193
struct iio_chan_spec *chan, int ch);
194+
static int ad7616_sw_mode_setup(struct iio_dev *indio_dev);
195+
static int ad7606b_sw_mode_setup(struct iio_dev *indio_dev);
190196

191197
const struct ad7606_chip_info ad7605_4_info = {
192198
.channels = ad7605_channels,
@@ -239,6 +245,7 @@ const struct ad7606_chip_info ad7606b_info = {
239245
.oversampling_avail = ad7606_oversampling_avail,
240246
.oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail),
241247
.scale_setup_cb = ad7606_16bit_chan_scale_setup,
248+
.sw_setup_cb = ad7606b_sw_mode_setup,
242249
};
243250
EXPORT_SYMBOL_NS_GPL(ad7606b_info, "IIO_AD7606");
244251

@@ -250,6 +257,7 @@ const struct ad7606_chip_info ad7606c_16_info = {
250257
.oversampling_avail = ad7606_oversampling_avail,
251258
.oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail),
252259
.scale_setup_cb = ad7606c_16bit_chan_scale_setup,
260+
.sw_setup_cb = ad7606b_sw_mode_setup,
253261
};
254262
EXPORT_SYMBOL_NS_GPL(ad7606c_16_info, "IIO_AD7606");
255263

@@ -294,6 +302,7 @@ const struct ad7606_chip_info ad7606c_18_info = {
294302
.oversampling_avail = ad7606_oversampling_avail,
295303
.oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail),
296304
.scale_setup_cb = ad7606c_18bit_chan_scale_setup,
305+
.sw_setup_cb = ad7606b_sw_mode_setup,
297306
};
298307
EXPORT_SYMBOL_NS_GPL(ad7606c_18_info, "IIO_AD7606");
299308

@@ -307,6 +316,7 @@ const struct ad7606_chip_info ad7616_info = {
307316
.oversampling_num = ARRAY_SIZE(ad7616_oversampling_avail),
308317
.os_req_reset = true,
309318
.scale_setup_cb = ad7606_16bit_chan_scale_setup,
319+
.sw_setup_cb = ad7616_sw_mode_setup,
310320
};
311321
EXPORT_SYMBOL_NS_GPL(ad7616_info, "IIO_AD7606");
312322

@@ -1138,16 +1148,118 @@ static const struct iio_trigger_ops ad7606_trigger_ops = {
11381148
.validate_device = iio_trigger_validate_own_device,
11391149
};
11401150

1141-
static int ad7606_sw_mode_setup(struct iio_dev *indio_dev)
1151+
static int ad7606_write_mask(struct ad7606_state *st, unsigned int addr,
1152+
unsigned long mask, unsigned int val)
1153+
{
1154+
int readval;
1155+
1156+
readval = st->bops->reg_read(st, addr);
1157+
if (readval < 0)
1158+
return readval;
1159+
1160+
readval &= ~mask;
1161+
readval |= val;
1162+
1163+
return st->bops->reg_write(st, addr, readval);
1164+
}
1165+
1166+
static int ad7616_write_scale_sw(struct iio_dev *indio_dev, int ch, int val)
11421167
{
11431168
struct ad7606_state *st = iio_priv(indio_dev);
1169+
unsigned int ch_addr, mode, ch_index;
11441170

1145-
st->sw_mode_en = st->bops->sw_mode_config &&
1146-
device_property_present(st->dev, "adi,sw-mode");
1147-
if (!st->sw_mode_en)
1148-
return 0;
1171+
/*
1172+
* Ad7616 has 16 channels divided in group A and group B.
1173+
* The range of channels from A are stored in registers with address 4
1174+
* while channels from B are stored in register with address 6.
1175+
* The last bit from channels determines if it is from group A or B
1176+
* because the order of channels in iio is 0A, 0B, 1A, 1B...
1177+
*/
1178+
ch_index = ch >> 1;
1179+
1180+
ch_addr = AD7616_RANGE_CH_ADDR(ch_index);
1181+
1182+
if ((ch & 0x1) == 0) /* channel A */
1183+
ch_addr += AD7616_RANGE_CH_A_ADDR_OFF;
1184+
else /* channel B */
1185+
ch_addr += AD7616_RANGE_CH_B_ADDR_OFF;
1186+
1187+
/* 0b01 for 2.5v, 0b10 for 5v and 0b11 for 10v */
1188+
mode = AD7616_RANGE_CH_MODE(ch_index, ((val + 1) & 0b11));
11491189

1150-
indio_dev->info = &ad7606_info_sw_mode;
1190+
return ad7606_write_mask(st, ch_addr, AD7616_RANGE_CH_MSK(ch_index),
1191+
mode);
1192+
}
1193+
1194+
static int ad7616_write_os_sw(struct iio_dev *indio_dev, int val)
1195+
{
1196+
struct ad7606_state *st = iio_priv(indio_dev);
1197+
1198+
return ad7606_write_mask(st, AD7616_CONFIGURATION_REGISTER,
1199+
AD7616_OS_MASK, val << 2);
1200+
}
1201+
1202+
static int ad7606_write_scale_sw(struct iio_dev *indio_dev, int ch, int val)
1203+
{
1204+
struct ad7606_state *st = iio_priv(indio_dev);
1205+
1206+
return ad7606_write_mask(st, AD7606_RANGE_CH_ADDR(ch),
1207+
AD7606_RANGE_CH_MSK(ch),
1208+
AD7606_RANGE_CH_MODE(ch, val));
1209+
}
1210+
1211+
static int ad7606_write_os_sw(struct iio_dev *indio_dev, int val)
1212+
{
1213+
struct ad7606_state *st = iio_priv(indio_dev);
1214+
1215+
return st->bops->reg_write(st, AD7606_OS_MODE, val);
1216+
}
1217+
1218+
static int ad7616_sw_mode_setup(struct iio_dev *indio_dev)
1219+
{
1220+
struct ad7606_state *st = iio_priv(indio_dev);
1221+
int ret;
1222+
1223+
/*
1224+
* Scale can be configured individually for each channel
1225+
* in software mode.
1226+
*/
1227+
1228+
st->write_scale = ad7616_write_scale_sw;
1229+
st->write_os = &ad7616_write_os_sw;
1230+
1231+
ret = st->bops->sw_mode_config(indio_dev);
1232+
if (ret)
1233+
return ret;
1234+
1235+
/* Activate Burst mode and SEQEN MODE */
1236+
return ad7606_write_mask(st, AD7616_CONFIGURATION_REGISTER,
1237+
AD7616_BURST_MODE | AD7616_SEQEN_MODE,
1238+
AD7616_BURST_MODE | AD7616_SEQEN_MODE);
1239+
}
1240+
1241+
static int ad7606b_sw_mode_setup(struct iio_dev *indio_dev)
1242+
{
1243+
struct ad7606_state *st = iio_priv(indio_dev);
1244+
DECLARE_BITMAP(os, 3);
1245+
1246+
bitmap_fill(os, 3);
1247+
/*
1248+
* Software mode is enabled when all three oversampling
1249+
* pins are set to high. If oversampling gpios are defined
1250+
* in the device tree, then they need to be set to high,
1251+
* otherwise, they must be hardwired to VDD
1252+
*/
1253+
if (st->gpio_os) {
1254+
gpiod_set_array_value(st->gpio_os->ndescs, st->gpio_os->desc,
1255+
st->gpio_os->info, os);
1256+
}
1257+
/* OS of 128 and 256 are available only in software mode */
1258+
st->oversampling_avail = ad7606b_oversampling_avail;
1259+
st->num_os_ratios = ARRAY_SIZE(ad7606b_oversampling_avail);
1260+
1261+
st->write_scale = ad7606_write_scale_sw;
1262+
st->write_os = &ad7606_write_os_sw;
11511263

11521264
return st->bops->sw_mode_config(indio_dev);
11531265
}
@@ -1326,9 +1438,12 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address,
13261438
st->write_scale = ad7606_write_scale_hw;
13271439
st->write_os = ad7606_write_os_hw;
13281440

1329-
ret = ad7606_sw_mode_setup(indio_dev);
1330-
if (ret)
1331-
return ret;
1441+
st->sw_mode_en = st->chip_info->sw_setup_cb &&
1442+
device_property_present(st->dev, "adi,sw-mode");
1443+
if (st->sw_mode_en) {
1444+
indio_dev->info = &ad7606_info_sw_mode;
1445+
st->chip_info->sw_setup_cb(indio_dev);
1446+
}
13321447

13331448
ret = ad7606_chan_scales_setup(indio_dev);
13341449
if (ret)

drivers/iio/adc/ad7606.h

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,36 @@
1010

1111
#define AD760X_MAX_CHANNELS 16
1212

13+
#define AD7616_CONFIGURATION_REGISTER 0x02
14+
#define AD7616_OS_MASK GENMASK(4, 2)
15+
#define AD7616_BURST_MODE BIT(6)
16+
#define AD7616_SEQEN_MODE BIT(5)
17+
#define AD7616_RANGE_CH_A_ADDR_OFF 0x04
18+
#define AD7616_RANGE_CH_B_ADDR_OFF 0x06
19+
/*
20+
* Range of channels from a group are stored in 2 registers.
21+
* 0, 1, 2, 3 in a register followed by 4, 5, 6, 7 in second register.
22+
* For channels from second group(8-15) the order is the same, only with
23+
* an offset of 2 for register address.
24+
*/
25+
#define AD7616_RANGE_CH_ADDR(ch) ((ch) >> 2)
26+
/* The range of the channel is stored in 2 bits */
27+
#define AD7616_RANGE_CH_MSK(ch) (0b11 << (((ch) & 0b11) * 2))
28+
#define AD7616_RANGE_CH_MODE(ch, mode) ((mode) << ((((ch) & 0b11)) * 2))
29+
30+
#define AD7606_CONFIGURATION_REGISTER 0x02
31+
#define AD7606_SINGLE_DOUT 0x00
32+
33+
/*
34+
* Range for AD7606B channels are stored in registers starting with address 0x3.
35+
* Each register stores range for 2 channels(4 bits per channel).
36+
*/
37+
#define AD7606_RANGE_CH_MSK(ch) (GENMASK(3, 0) << (4 * ((ch) & 0x1)))
38+
#define AD7606_RANGE_CH_MODE(ch, mode) \
39+
((GENMASK(3, 0) & (mode)) << (4 * ((ch) & 0x1)))
40+
#define AD7606_RANGE_CH_ADDR(ch) (0x03 + ((ch) >> 1))
41+
#define AD7606_OS_MODE 0x08
42+
1343
#define AD760X_CHANNEL(num, mask_sep, mask_type, mask_all, bits) { \
1444
.type = IIO_VOLTAGE, \
1545
.indexed = 1, \
@@ -71,6 +101,7 @@ struct ad7606_state;
71101

72102
typedef int (*ad7606_scale_setup_cb_t)(struct iio_dev *indio_dev,
73103
struct iio_chan_spec *chan, int ch);
104+
typedef int (*ad7606_sw_setup_cb_t)(struct iio_dev *indio_dev);
74105

75106
/**
76107
* struct ad7606_chip_info - chip specific information
@@ -80,6 +111,7 @@ typedef int (*ad7606_scale_setup_cb_t)(struct iio_dev *indio_dev,
80111
* @num_channels: number of channels
81112
* @num_adc_channels the number of channels the ADC actually inputs.
82113
* @scale_setup_cb: callback to setup the scales for each channel
114+
* @sw_setup_cb: callback to setup the software mode if available.
83115
* @oversampling_avail pointer to the array which stores the available
84116
* oversampling ratios.
85117
* @oversampling_num number of elements stored in oversampling_avail array
@@ -94,6 +126,7 @@ struct ad7606_chip_info {
94126
unsigned int num_adc_channels;
95127
unsigned int num_channels;
96128
ad7606_scale_setup_cb_t scale_setup_cb;
129+
ad7606_sw_setup_cb_t sw_setup_cb;
97130
const unsigned int *oversampling_avail;
98131
unsigned int oversampling_num;
99132
bool os_req_reset;
@@ -206,10 +239,6 @@ struct ad7606_bus_ops {
206239
int (*reg_write)(struct ad7606_state *st,
207240
unsigned int addr,
208241
unsigned int val);
209-
int (*write_mask)(struct ad7606_state *st,
210-
unsigned int addr,
211-
unsigned long mask,
212-
unsigned int val);
213242
int (*update_scan_mode)(struct iio_dev *indio_dev, const unsigned long *scan_mask);
214243
u16 (*rd_wr_cmd)(int addr, char isWriteOp);
215244
};

0 commit comments

Comments
 (0)