1 // SPDX-License-Identifier: GPL-2.0+
3 * AD5770R Digital to analog converters driver
5 * Copyright 2018 Analog Devices Inc.
8 #include <linux/bits.h>
9 #include <linux/delay.h>
10 #include <linux/device.h>
11 #include <linux/gpio/consumer.h>
12 #include <linux/iio/iio.h>
13 #include <linux/iio/sysfs.h>
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/property.h>
17 #include <linux/regmap.h>
18 #include <linux/regulator/consumer.h>
19 #include <linux/spi/spi.h>
20 #include <linux/unaligned.h>
22 #define ADI_SPI_IF_CONFIG_A 0x00
23 #define ADI_SPI_IF_CONFIG_B 0x01
24 #define ADI_SPI_IF_DEVICE_CONFIG 0x02
25 #define ADI_SPI_IF_CHIP_TYPE 0x03
26 #define ADI_SPI_IF_PRODUCT_ID_L 0x04
27 #define ADI_SPI_IF_PRODUCT_ID_H 0x05
28 #define ADI_SPI_IF_CHIP_GRADE 0x06
29 #define ADI_SPI_IF_SCRACTH_PAD 0x0A
30 #define ADI_SPI_IF_SPI_REVISION 0x0B
31 #define ADI_SPI_IF_SPI_VENDOR_L 0x0C
32 #define ADI_SPI_IF_SPI_VENDOR_H 0x0D
33 #define ADI_SPI_IF_SPI_STREAM_MODE 0x0E
34 #define ADI_SPI_IF_CONFIG_C 0x10
35 #define ADI_SPI_IF_STATUS_A 0x11
37 /* ADI_SPI_IF_CONFIG_A */
38 #define ADI_SPI_IF_SW_RESET_MSK (BIT(0) | BIT(7))
39 #define ADI_SPI_IF_SW_RESET_SEL(x) ((x) & ADI_SPI_IF_SW_RESET_MSK)
40 #define ADI_SPI_IF_ADDR_ASC_MSK (BIT(2) | BIT(5))
41 #define ADI_SPI_IF_ADDR_ASC_SEL(x) (((x) << 2) & ADI_SPI_IF_ADDR_ASC_MSK)
43 /* ADI_SPI_IF_CONFIG_B */
44 #define ADI_SPI_IF_SINGLE_INS_MSK BIT(7)
45 #define ADI_SPI_IF_SINGLE_INS_SEL(x) FIELD_PREP(ADI_SPI_IF_SINGLE_INS_MSK, x)
46 #define ADI_SPI_IF_SHORT_INS_MSK BIT(7)
47 #define ADI_SPI_IF_SHORT_INS_SEL(x) FIELD_PREP(ADI_SPI_IF_SINGLE_INS_MSK, x)
49 /* ADI_SPI_IF_CONFIG_C */
50 #define ADI_SPI_IF_STRICT_REG_MSK BIT(5)
51 #define ADI_SPI_IF_STRICT_REG_GET(x) FIELD_GET(ADI_SPI_IF_STRICT_REG_MSK, x)
53 /* AD5770R configuration registers */
54 #define AD5770R_CHANNEL_CONFIG 0x14
55 #define AD5770R_OUTPUT_RANGE(ch) (0x15 + (ch))
56 #define AD5770R_FILTER_RESISTOR(ch) (0x1D + (ch))
57 #define AD5770R_REFERENCE 0x1B
58 #define AD5770R_DAC_LSB(ch) (0x26 + 2 * (ch))
59 #define AD5770R_DAC_MSB(ch) (0x27 + 2 * (ch))
60 #define AD5770R_CH_SELECT 0x34
61 #define AD5770R_CH_ENABLE 0x44
63 /* AD5770R_CHANNEL_CONFIG */
64 #define AD5770R_CFG_CH0_SINK_EN(x) (((x) & 0x1) << 7)
65 #define AD5770R_CFG_SHUTDOWN_B(x, ch) (((x) & 0x1) << (ch))
67 /* AD5770R_OUTPUT_RANGE */
68 #define AD5770R_RANGE_OUTPUT_SCALING(x) (((x) & GENMASK(5, 0)) << 2)
69 #define AD5770R_RANGE_MODE(x) ((x) & GENMASK(1, 0))
71 /* AD5770R_REFERENCE */
72 #define AD5770R_REF_RESISTOR_SEL(x) (((x) & 0x1) << 2)
73 #define AD5770R_REF_SEL(x) ((x) & GENMASK(1, 0))
75 /* AD5770R_CH_ENABLE */
76 #define AD5770R_CH_SET(x, ch) (((x) & 0x1) << (ch))
78 #define AD5770R_MAX_CHANNELS 6
79 #define AD5770R_MAX_CH_MODES 14
80 #define AD5770R_LOW_VREF_mV 1250
81 #define AD5770R_HIGH_VREF_mV 2500
83 enum ad5770r_ch0_modes
{
84 AD5770R_CH0_0_300
= 0,
86 AD5770R_CH0_NEG_60_300
89 enum ad5770r_ch1_modes
{
90 AD5770R_CH1_0_140_LOW_HEAD
= 1,
91 AD5770R_CH1_0_140_LOW_NOISE
,
95 enum ad5770r_ch2_5_modes
{
96 AD5770R_CH_LOW_RANGE
= 0,
101 AD5770R_EXT_2_5_V
= 0,
102 AD5770R_INT_1_25_V_OUT_ON
,
104 AD5770R_INT_1_25_V_OUT_OFF
107 enum ad5770r_output_filter_resistor
{
108 AD5770R_FILTER_60_OHM
= 0x0,
109 AD5770R_FILTER_5_6_KOHM
= 0x5,
110 AD5770R_FILTER_11_2_KOHM
,
111 AD5770R_FILTER_22_2_KOHM
,
112 AD5770R_FILTER_44_4_KOHM
,
113 AD5770R_FILTER_104_KOHM
,
116 struct ad5770r_out_range
{
122 * struct ad5770r_state - driver instance specific data
125 * @gpio_reset: gpio descriptor
126 * @output_mode: array contains channels output ranges
127 * @vref: reference value
128 * @ch_pwr_down: powerdown flags
129 * @internal_ref: internal reference flag
130 * @external_res: external 2.5k resistor flag
131 * @transf_buf: cache aligned buffer for spi read/write
133 struct ad5770r_state
{
134 struct spi_device
*spi
;
135 struct regmap
*regmap
;
136 struct gpio_desc
*gpio_reset
;
137 struct ad5770r_out_range output_mode
[AD5770R_MAX_CHANNELS
];
139 bool ch_pwr_down
[AD5770R_MAX_CHANNELS
];
142 u8 transf_buf
[2] __aligned(IIO_DMA_MINALIGN
);
145 static const struct regmap_config ad5770r_spi_regmap_config
= {
148 .read_flag_mask
= BIT(7),
151 struct ad5770r_output_modes
{
158 static struct ad5770r_output_modes ad5770r_rng_tbl
[] = {
159 { 0, AD5770R_CH0_0_300
, 0, 300 },
160 { 0, AD5770R_CH0_NEG_60_0
, -60, 0 },
161 { 0, AD5770R_CH0_NEG_60_300
, -60, 300 },
162 { 1, AD5770R_CH1_0_140_LOW_HEAD
, 0, 140 },
163 { 1, AD5770R_CH1_0_140_LOW_NOISE
, 0, 140 },
164 { 1, AD5770R_CH1_0_250
, 0, 250 },
165 { 2, AD5770R_CH_LOW_RANGE
, 0, 55 },
166 { 2, AD5770R_CH_HIGH_RANGE
, 0, 150 },
167 { 3, AD5770R_CH_LOW_RANGE
, 0, 45 },
168 { 3, AD5770R_CH_HIGH_RANGE
, 0, 100 },
169 { 4, AD5770R_CH_LOW_RANGE
, 0, 45 },
170 { 4, AD5770R_CH_HIGH_RANGE
, 0, 100 },
171 { 5, AD5770R_CH_LOW_RANGE
, 0, 45 },
172 { 5, AD5770R_CH_HIGH_RANGE
, 0, 100 },
175 static const unsigned int ad5770r_filter_freqs
[] = {
176 153, 357, 715, 1400, 2800, 262000,
179 static const unsigned int ad5770r_filter_reg_vals
[] = {
180 AD5770R_FILTER_104_KOHM
,
181 AD5770R_FILTER_44_4_KOHM
,
182 AD5770R_FILTER_22_2_KOHM
,
183 AD5770R_FILTER_11_2_KOHM
,
184 AD5770R_FILTER_5_6_KOHM
,
185 AD5770R_FILTER_60_OHM
188 static int ad5770r_set_output_mode(struct ad5770r_state
*st
,
189 const struct ad5770r_out_range
*out_mode
,
194 regval
= AD5770R_RANGE_OUTPUT_SCALING(out_mode
->out_scale
) |
195 AD5770R_RANGE_MODE(out_mode
->out_range_mode
);
197 return regmap_write(st
->regmap
,
198 AD5770R_OUTPUT_RANGE(channel
), regval
);
201 static int ad5770r_set_reference(struct ad5770r_state
*st
)
205 regval
= AD5770R_REF_RESISTOR_SEL(st
->external_res
);
207 if (st
->internal_ref
) {
208 regval
|= AD5770R_REF_SEL(AD5770R_INT_1_25_V_OUT_OFF
);
211 case AD5770R_LOW_VREF_mV
:
212 regval
|= AD5770R_REF_SEL(AD5770R_EXT_1_25_V
);
214 case AD5770R_HIGH_VREF_mV
:
215 regval
|= AD5770R_REF_SEL(AD5770R_EXT_2_5_V
);
218 regval
= AD5770R_REF_SEL(AD5770R_INT_1_25_V_OUT_OFF
);
223 return regmap_write(st
->regmap
, AD5770R_REFERENCE
, regval
);
226 static int ad5770r_soft_reset(struct ad5770r_state
*st
)
228 return regmap_write(st
->regmap
, ADI_SPI_IF_CONFIG_A
,
229 ADI_SPI_IF_SW_RESET_SEL(1));
232 static int ad5770r_reset(struct ad5770r_state
*st
)
234 /* Perform software reset if no GPIO provided */
236 return ad5770r_soft_reset(st
);
238 gpiod_set_value_cansleep(st
->gpio_reset
, 0);
239 usleep_range(10, 20);
240 gpiod_set_value_cansleep(st
->gpio_reset
, 1);
242 /* data must not be written during reset timeframe */
243 usleep_range(100, 200);
248 static int ad5770r_get_range(struct ad5770r_state
*st
,
249 int ch
, int *min
, int *max
)
252 u8 tbl_ch
, tbl_mode
, out_range
;
254 out_range
= st
->output_mode
[ch
].out_range_mode
;
256 for (i
= 0; i
< AD5770R_MAX_CH_MODES
; i
++) {
257 tbl_ch
= ad5770r_rng_tbl
[i
].ch
;
258 tbl_mode
= ad5770r_rng_tbl
[i
].mode
;
259 if (tbl_ch
== ch
&& tbl_mode
== out_range
) {
260 *min
= ad5770r_rng_tbl
[i
].min
;
261 *max
= ad5770r_rng_tbl
[i
].max
;
269 static int ad5770r_get_filter_freq(struct iio_dev
*indio_dev
,
270 const struct iio_chan_spec
*chan
, int *freq
)
272 struct ad5770r_state
*st
= iio_priv(indio_dev
);
274 unsigned int regval
, i
;
276 ret
= regmap_read(st
->regmap
,
277 AD5770R_FILTER_RESISTOR(chan
->channel
), ®val
);
281 for (i
= 0; i
< ARRAY_SIZE(ad5770r_filter_reg_vals
); i
++)
282 if (regval
== ad5770r_filter_reg_vals
[i
])
284 if (i
== ARRAY_SIZE(ad5770r_filter_reg_vals
))
287 *freq
= ad5770r_filter_freqs
[i
];
292 static int ad5770r_set_filter_freq(struct iio_dev
*indio_dev
,
293 const struct iio_chan_spec
*chan
,
296 struct ad5770r_state
*st
= iio_priv(indio_dev
);
297 unsigned int regval
, i
;
299 for (i
= 0; i
< ARRAY_SIZE(ad5770r_filter_freqs
); i
++)
300 if (ad5770r_filter_freqs
[i
] >= freq
)
302 if (i
== ARRAY_SIZE(ad5770r_filter_freqs
))
305 regval
= ad5770r_filter_reg_vals
[i
];
307 return regmap_write(st
->regmap
, AD5770R_FILTER_RESISTOR(chan
->channel
),
311 static int ad5770r_read_raw(struct iio_dev
*indio_dev
,
312 struct iio_chan_spec
const *chan
,
313 int *val
, int *val2
, long info
)
315 struct ad5770r_state
*st
= iio_priv(indio_dev
);
320 case IIO_CHAN_INFO_RAW
:
321 ret
= regmap_bulk_read(st
->regmap
,
327 buf16
= get_unaligned_le16(st
->transf_buf
);
330 case IIO_CHAN_INFO_SCALE
:
331 ret
= ad5770r_get_range(st
, chan
->channel
, &min
, &max
);
335 /* There is no sign bit. (negative current is mapped from 0)
336 * (sourced/sinked) current = raw * scale + offset
337 * where offset in case of CH0 can be negative.
340 return IIO_VAL_FRACTIONAL_LOG2
;
341 case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY
:
342 return ad5770r_get_filter_freq(indio_dev
, chan
, val
);
343 case IIO_CHAN_INFO_OFFSET
:
344 ret
= ad5770r_get_range(st
, chan
->channel
, &min
, &max
);
354 static int ad5770r_write_raw(struct iio_dev
*indio_dev
,
355 struct iio_chan_spec
const *chan
,
356 int val
, int val2
, long info
)
358 struct ad5770r_state
*st
= iio_priv(indio_dev
);
361 case IIO_CHAN_INFO_RAW
:
362 st
->transf_buf
[0] = ((u16
)val
>> 6);
363 st
->transf_buf
[1] = (val
& GENMASK(5, 0)) << 2;
364 return regmap_bulk_write(st
->regmap
, chan
->address
,
366 case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY
:
367 return ad5770r_set_filter_freq(indio_dev
, chan
, val
);
373 static int ad5770r_read_freq_avail(struct iio_dev
*indio_dev
,
374 struct iio_chan_spec
const *chan
,
375 const int **vals
, int *type
, int *length
,
379 case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY
:
381 *vals
= ad5770r_filter_freqs
;
382 *length
= ARRAY_SIZE(ad5770r_filter_freqs
);
383 return IIO_AVAIL_LIST
;
389 static int ad5770r_reg_access(struct iio_dev
*indio_dev
,
391 unsigned int writeval
,
392 unsigned int *readval
)
394 struct ad5770r_state
*st
= iio_priv(indio_dev
);
397 return regmap_read(st
->regmap
, reg
, readval
);
399 return regmap_write(st
->regmap
, reg
, writeval
);
402 static const struct iio_info ad5770r_info
= {
403 .read_raw
= ad5770r_read_raw
,
404 .write_raw
= ad5770r_write_raw
,
405 .read_avail
= ad5770r_read_freq_avail
,
406 .debugfs_reg_access
= &ad5770r_reg_access
,
409 static int ad5770r_store_output_range(struct ad5770r_state
*st
,
410 int min
, int max
, int index
)
414 for (i
= 0; i
< AD5770R_MAX_CH_MODES
; i
++) {
415 if (ad5770r_rng_tbl
[i
].ch
!= index
)
417 if (ad5770r_rng_tbl
[i
].min
!= min
||
418 ad5770r_rng_tbl
[i
].max
!= max
)
420 st
->output_mode
[index
].out_range_mode
= ad5770r_rng_tbl
[i
].mode
;
428 static ssize_t
ad5770r_read_dac_powerdown(struct iio_dev
*indio_dev
,
430 const struct iio_chan_spec
*chan
,
433 struct ad5770r_state
*st
= iio_priv(indio_dev
);
435 return sysfs_emit(buf
, "%d\n", st
->ch_pwr_down
[chan
->channel
]);
438 static ssize_t
ad5770r_write_dac_powerdown(struct iio_dev
*indio_dev
,
440 const struct iio_chan_spec
*chan
,
441 const char *buf
, size_t len
)
443 struct ad5770r_state
*st
= iio_priv(indio_dev
);
449 ret
= kstrtobool(buf
, &readin
);
455 regval
= AD5770R_CFG_SHUTDOWN_B(readin
, chan
->channel
);
456 if (chan
->channel
== 0 &&
457 st
->output_mode
[0].out_range_mode
> AD5770R_CH0_0_300
) {
458 regval
|= AD5770R_CFG_CH0_SINK_EN(readin
);
459 mask
= BIT(chan
->channel
) + BIT(7);
461 mask
= BIT(chan
->channel
);
463 ret
= regmap_update_bits(st
->regmap
, AD5770R_CHANNEL_CONFIG
, mask
,
468 regval
= AD5770R_CH_SET(readin
, chan
->channel
);
469 ret
= regmap_update_bits(st
->regmap
, AD5770R_CH_ENABLE
,
470 BIT(chan
->channel
), regval
);
474 st
->ch_pwr_down
[chan
->channel
] = !readin
;
479 static const struct iio_chan_spec_ext_info ad5770r_ext_info
[] = {
482 .read
= ad5770r_read_dac_powerdown
,
483 .write
= ad5770r_write_dac_powerdown
,
484 .shared
= IIO_SEPARATE
,
489 #define AD5770R_IDAC_CHANNEL(index, reg) { \
490 .type = IIO_CURRENT, \
495 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
496 BIT(IIO_CHAN_INFO_SCALE) | \
497 BIT(IIO_CHAN_INFO_OFFSET) | \
498 BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \
499 .info_mask_shared_by_type_available = \
500 BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \
501 .ext_info = ad5770r_ext_info, \
504 static const struct iio_chan_spec ad5770r_channels
[] = {
505 AD5770R_IDAC_CHANNEL(0, AD5770R_DAC_MSB(0)),
506 AD5770R_IDAC_CHANNEL(1, AD5770R_DAC_MSB(1)),
507 AD5770R_IDAC_CHANNEL(2, AD5770R_DAC_MSB(2)),
508 AD5770R_IDAC_CHANNEL(3, AD5770R_DAC_MSB(3)),
509 AD5770R_IDAC_CHANNEL(4, AD5770R_DAC_MSB(4)),
510 AD5770R_IDAC_CHANNEL(5, AD5770R_DAC_MSB(5)),
513 static int ad5770r_channel_config(struct ad5770r_state
*st
)
515 int ret
, tmp
[2], min
, max
;
518 num
= device_get_child_node_count(&st
->spi
->dev
);
519 if (num
!= AD5770R_MAX_CHANNELS
)
522 device_for_each_child_node_scoped(&st
->spi
->dev
, child
) {
523 ret
= fwnode_property_read_u32(child
, "reg", &num
);
526 if (num
>= AD5770R_MAX_CHANNELS
)
529 ret
= fwnode_property_read_u32_array(child
,
530 "adi,range-microamp",
537 ret
= ad5770r_store_output_range(st
, min
, max
, num
);
545 static int ad5770r_init(struct ad5770r_state
*st
)
549 st
->gpio_reset
= devm_gpiod_get_optional(&st
->spi
->dev
, "reset",
551 if (IS_ERR(st
->gpio_reset
))
552 return PTR_ERR(st
->gpio_reset
);
554 /* Perform a reset */
555 ret
= ad5770r_reset(st
);
559 /* Set output range */
560 ret
= ad5770r_channel_config(st
);
564 for (i
= 0; i
< AD5770R_MAX_CHANNELS
; i
++) {
565 ret
= ad5770r_set_output_mode(st
, &st
->output_mode
[i
], i
);
570 st
->external_res
= fwnode_property_read_bool(st
->spi
->dev
.fwnode
,
571 "adi,external-resistor");
573 ret
= ad5770r_set_reference(st
);
577 /* Set outputs off */
578 ret
= regmap_write(st
->regmap
, AD5770R_CHANNEL_CONFIG
, 0x00);
582 ret
= regmap_write(st
->regmap
, AD5770R_CH_ENABLE
, 0x00);
586 for (i
= 0; i
< AD5770R_MAX_CHANNELS
; i
++)
587 st
->ch_pwr_down
[i
] = true;
592 static int ad5770r_probe(struct spi_device
*spi
)
594 struct ad5770r_state
*st
;
595 struct iio_dev
*indio_dev
;
596 struct regmap
*regmap
;
599 indio_dev
= devm_iio_device_alloc(&spi
->dev
, sizeof(*st
));
603 st
= iio_priv(indio_dev
);
604 spi_set_drvdata(spi
, indio_dev
);
608 regmap
= devm_regmap_init_spi(spi
, &ad5770r_spi_regmap_config
);
609 if (IS_ERR(regmap
)) {
610 dev_err(&spi
->dev
, "Error initializing spi regmap: %ld\n",
612 return PTR_ERR(regmap
);
616 ret
= devm_regulator_get_enable_read_voltage(&spi
->dev
, "vref");
617 if (ret
< 0 && ret
!= -ENODEV
)
618 return dev_err_probe(&spi
->dev
, ret
, "Failed to get vref voltage\n");
620 st
->internal_ref
= ret
== -ENODEV
;
621 st
->vref
= st
->internal_ref
? AD5770R_LOW_VREF_mV
: ret
/ 1000;
623 indio_dev
->name
= spi_get_device_id(spi
)->name
;
624 indio_dev
->info
= &ad5770r_info
;
625 indio_dev
->modes
= INDIO_DIRECT_MODE
;
626 indio_dev
->channels
= ad5770r_channels
;
627 indio_dev
->num_channels
= ARRAY_SIZE(ad5770r_channels
);
629 ret
= ad5770r_init(st
);
631 dev_err(&spi
->dev
, "AD5770R init failed\n");
635 return devm_iio_device_register(&st
->spi
->dev
, indio_dev
);
638 static const struct of_device_id ad5770r_of_id
[] = {
639 { .compatible
= "adi,ad5770r", },
642 MODULE_DEVICE_TABLE(of
, ad5770r_of_id
);
644 static const struct spi_device_id ad5770r_id
[] = {
648 MODULE_DEVICE_TABLE(spi
, ad5770r_id
);
650 static struct spi_driver ad5770r_driver
= {
652 .name
= KBUILD_MODNAME
,
653 .of_match_table
= ad5770r_of_id
,
655 .probe
= ad5770r_probe
,
656 .id_table
= ad5770r_id
,
659 module_spi_driver(ad5770r_driver
);
661 MODULE_AUTHOR("Mircea Caprioru <mircea.caprioru@analog.com>");
662 MODULE_DESCRIPTION("Analog Devices AD5770R IDAC");
663 MODULE_LICENSE("GPL v2");