Skip to content

Commit 1c68579

Browse files
committed
iio:dac:ad5686: Add AD5681R/AD5682R/AD5683/AD5683R support
The AD5681R/AD5682R/AD5683/AD5683R are a family of one channel DACs with 12-bit, 14-bit and 16-bit precision respectively. The devices have either no built-in reference, or built-in 2.5V reference. These devices are simmilar to AD5691R/AD5692R/AD5693/AD5693R except that they use the spi interface instead of i2c. Another difference is that in the write control register, DB18 and DB17 are used for setting the power mode, while DB16 is the REF bit. In order to accomodate this change, a new regmap type was defined and checked accordingly. Datasheet: http://www.analog.com/media/en/technical-documentation/data-sheets/AD5683R_5682R_5681R_5683.pdf Signed-off-by: Stefan Popa <[email protected]>
1 parent 078d595 commit 1c68579

File tree

3 files changed

+82
-18
lines changed

3 files changed

+82
-18
lines changed

drivers/iio/dac/ad5686-spi.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
2-
* AD5672R, AD5676, AD5676R, AD5684, AD5684R, AD5684R, AD5685R, AD5686, AD5686R
2+
* AD5672R, AD5676, AD5676R, AD5681R, AD5682R, AD5683, AD5683R,
3+
* AD5684, AD5684R, AD5685R, AD5686, AD5686R
34
* Digital to analog converters driver
45
*
56
* Copyright 2018 Analog Devices Inc.
@@ -38,9 +39,15 @@ static int ad5686_spi_read(struct ad5686_state *st, u8 addr)
3839
},
3940
};
4041
struct spi_device *spi = to_spi_device(st->dev);
42+
u8 cmd;
4143
int ret;
4244

43-
st->data[0].d32 = cpu_to_be32(AD5686_CMD(AD5686_CMD_READBACK_ENABLE) |
45+
if (st->chip_info->regmap_type == AD5686_REGMAP)
46+
cmd = AD5686_CMD_READBACK_ENABLE;
47+
else if (st->chip_info->regmap_type == AD5683_REGMAP)
48+
cmd = AD5686_CMD_READBACK_ENABLE_V2;
49+
50+
st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) |
4451
AD5686_ADDR(addr));
4552
st->data[1].d32 = cpu_to_be32(AD5686_CMD(AD5686_CMD_NOOP));
4653

@@ -68,6 +75,10 @@ static const struct spi_device_id ad5686_spi_id[] = {
6875
{"ad5672r", ID_AD5672R},
6976
{"ad5676", ID_AD5676},
7077
{"ad5676r", ID_AD5676R},
78+
{"ad5681r", ID_AD5681R},
79+
{"ad5682r", ID_AD5682R},
80+
{"ad5683", ID_AD5683},
81+
{"ad5683r", ID_AD5683R},
7182
{"ad5684", ID_AD5684},
7283
{"ad5684r", ID_AD5684R},
7384
{"ad5685r", ID_AD5685R},

drivers/iio/dac/ad5686.c

Lines changed: 59 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev,
8282
bool readin;
8383
int ret;
8484
struct ad5686_state *st = iio_priv(indio_dev);
85-
unsigned int val;
85+
unsigned int val, ref_bit_msk;
86+
u8 shift;
8687

8788
ret = strtobool(buf, &readin);
8889
if (ret)
@@ -93,13 +94,24 @@ static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev,
9394
else
9495
st->pwr_down_mask &= ~(0x3 << (chan->channel * 2));
9596

96-
if (st->chip_info->regmap_type == AD5693_REGMAP) {
97-
val = ((st->pwr_down_mask & st->pwr_down_mode) << 13) |
98-
(st->use_internal_vref == true ? 0 : (1 << 12));
99-
} else {
100-
val = st->pwr_down_mask & st->pwr_down_mode;
97+
switch (st->chip_info->regmap_type) {
98+
case AD5686_REGMAP:
99+
shift = 0;
100+
break;
101+
case AD5693_REGMAP:
102+
shift = 13;
103+
ref_bit_msk = AD5693_REF_BIT_MSK;
104+
break;
105+
case AD5683_REGMAP:
106+
shift = 17;
107+
ref_bit_msk = AD5683_REF_BIT_MSK;
108+
break;
101109
}
102110

111+
val = ((st->pwr_down_mask & st->pwr_down_mode) << shift);
112+
if (!st->use_internal_vref)
113+
val |= ref_bit_msk;
114+
103115
ret = ad5686_write(st, AD5686_CMD_POWERDOWN_DAC, 0, val, 0);
104116

105117
return ret ? ret : len;
@@ -259,6 +271,29 @@ static const struct ad5686_chip_info ad5686_chip_info_tbl[] = {
259271
.num_channels = 8,
260272
.regmap_type = AD5686_REGMAP,
261273
},
274+
[ID_AD5681R] = {
275+
.channels = ad5691r_channels,
276+
.int_vref_mv = 2500,
277+
.num_channels = 1,
278+
.regmap_type = AD5683_REGMAP,
279+
},
280+
[ID_AD5682R] = {
281+
.channels = ad5692r_channels,
282+
.int_vref_mv = 2500,
283+
.num_channels = 1,
284+
.regmap_type = AD5683_REGMAP,
285+
},
286+
[ID_AD5683] = {
287+
.channels = ad5693_channels,
288+
.num_channels = 1,
289+
.regmap_type = AD5683_REGMAP,
290+
},
291+
[ID_AD5683R] = {
292+
.channels = ad5693_channels,
293+
.int_vref_mv = 2500,
294+
.num_channels = 1,
295+
.regmap_type = AD5683_REGMAP,
296+
},
262297
[ID_AD5684] = {
263298
.channels = ad5684_channels,
264299
.num_channels = 4,
@@ -339,7 +374,8 @@ int ad5686_probe(struct device *dev, enum ad5686_supported_device_ids chip_type,
339374
{
340375
struct ad5686_state *st;
341376
struct iio_dev *indio_dev;
342-
u8 shift, cmd;
377+
u8 cmd;
378+
unsigned int val, ref_bit_msk;
343379
int ret, i, voltage_uv = 0;
344380

345381
indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
@@ -384,16 +420,26 @@ int ad5686_probe(struct device *dev, enum ad5686_supported_device_ids chip_type,
384420
indio_dev->channels = st->chip_info->channels;
385421
indio_dev->num_channels = st->chip_info->num_channels;
386422

387-
if (st->chip_info->regmap_type == AD5693_REGMAP) {
423+
switch (st->chip_info->regmap_type) {
424+
case AD5686_REGMAP:
425+
cmd = AD5686_CMD_INTERNAL_REFER_SETUP;
426+
ref_bit_msk = 0;
427+
break;
428+
case AD5693_REGMAP:
429+
cmd = AD5686_CMD_CONTROL_REG;
430+
ref_bit_msk = AD5693_REF_BIT_MSK;
388431
st->use_internal_vref = !voltage_uv;
432+
break;
433+
case AD5683_REGMAP:
389434
cmd = AD5686_CMD_CONTROL_REG;
390-
shift = 12;
391-
} else {
392-
cmd = AD5686_CMD_INTERNAL_REFER_SETUP;
393-
shift = 0;
435+
ref_bit_msk = AD5683_REF_BIT_MSK;
436+
st->use_internal_vref = !voltage_uv;
437+
break;
394438
}
395439

396-
ret = ad5686_write(st, cmd, 0, !!voltage_uv, shift);
440+
val = (voltage_uv | ref_bit_msk);
441+
442+
ret = ad5686_write(st, cmd, 0, !!val, 0);
397443
if (ret)
398444
goto error_disable_reg;
399445

drivers/iio/dac/ad5686.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
#define AD5686_LDAC_PWRDN_3STATE 0x3
3030

3131
#define AD5686_CMD_CONTROL_REG 0x4
32+
#define AD5686_CMD_READBACK_ENABLE_V2 0x5
33+
#define AD5683_REF_BIT_MSK BIT(16)
34+
#define AD5693_REF_BIT_MSK BIT(12)
3235

3336
/**
3437
* ad5686_supported_device_ids:
@@ -39,6 +42,10 @@ enum ad5686_supported_device_ids {
3942
ID_AD5675R,
4043
ID_AD5676,
4144
ID_AD5676R,
45+
ID_AD5681R,
46+
ID_AD5682R,
47+
ID_AD5683,
48+
ID_AD5683R,
4249
ID_AD5684,
4350
ID_AD5684R,
4451
ID_AD5685R,
@@ -56,8 +63,9 @@ enum ad5686_supported_device_ids {
5663
};
5764

5865
enum ad5686_regmap_type {
66+
AD5683_REGMAP,
5967
AD5686_REGMAP,
60-
AD5693_REGMAP
68+
AD5693_REGMAP,
6169
};
6270

6371
struct ad5686_state;
@@ -90,8 +98,7 @@ struct ad5686_chip_info {
9098
* @vref_mv: actual reference voltage used
9199
* @pwr_down_mask: power down mask
92100
* @pwr_down_mode: current power down mode
93-
* @use_internal_vref: set to true if the internal reference voltage should be
94-
* used.
101+
* @use_internal_vref: set to true if the internal reference voltage is used
95102
* @data: spi transfer buffers
96103
*/
97104

0 commit comments

Comments
 (0)