1 // SPDX-License-Identifier: GPL-2.0-only
3 * AD5592R Digital <-> Analog converters driver
5 * Copyright 2015-2016 Analog Devices Inc.
6 * Author: Paul Cercueil <paul.cercueil@analog.com>
9 #include "ad5592r-base.h"
11 #include <linux/bitops.h>
12 #include <linux/module.h>
14 #include <linux/spi/spi.h>
15 #include <linux/acpi.h>
17 #define AD5592R_GPIO_READBACK_EN BIT(10)
18 #define AD5592R_LDAC_READBACK_EN BIT(6)
20 static int ad5592r_spi_wnop_r16(struct ad5592r_state
*st
, __be16
*buf
)
22 struct spi_device
*spi
= container_of(st
->dev
, struct spi_device
, dev
);
23 struct spi_transfer t
= {
24 .tx_buf
= &st
->spi_msg_nop
,
29 st
->spi_msg_nop
= 0; /* NOP */
31 return spi_sync_transfer(spi
, &t
, 1);
34 static int ad5592r_write_dac(struct ad5592r_state
*st
, unsigned chan
, u16 value
)
36 struct spi_device
*spi
= container_of(st
->dev
, struct spi_device
, dev
);
38 st
->spi_msg
= cpu_to_be16(BIT(15) | (chan
<< 12) | value
);
40 return spi_write(spi
, &st
->spi_msg
, sizeof(st
->spi_msg
));
43 static int ad5592r_read_adc(struct ad5592r_state
*st
, unsigned chan
, u16
*value
)
45 struct spi_device
*spi
= container_of(st
->dev
, struct spi_device
, dev
);
48 st
->spi_msg
= cpu_to_be16((AD5592R_REG_ADC_SEQ
<< 11) | BIT(chan
));
50 ret
= spi_write(spi
, &st
->spi_msg
, sizeof(st
->spi_msg
));
56 * See Figure 40. Single-Channel ADC Conversion Sequence
58 ret
= ad5592r_spi_wnop_r16(st
, &st
->spi_msg
);
62 ret
= ad5592r_spi_wnop_r16(st
, &st
->spi_msg
);
66 *value
= be16_to_cpu(st
->spi_msg
);
71 static int ad5592r_reg_write(struct ad5592r_state
*st
, u8 reg
, u16 value
)
73 struct spi_device
*spi
= container_of(st
->dev
, struct spi_device
, dev
);
75 st
->spi_msg
= cpu_to_be16((reg
<< 11) | value
);
77 return spi_write(spi
, &st
->spi_msg
, sizeof(st
->spi_msg
));
80 static int ad5592r_reg_read(struct ad5592r_state
*st
, u8 reg
, u16
*value
)
82 struct spi_device
*spi
= container_of(st
->dev
, struct spi_device
, dev
);
85 st
->spi_msg
= cpu_to_be16((AD5592R_REG_LDAC
<< 11) |
86 AD5592R_LDAC_READBACK_EN
| (reg
<< 2));
88 ret
= spi_write(spi
, &st
->spi_msg
, sizeof(st
->spi_msg
));
92 ret
= ad5592r_spi_wnop_r16(st
, &st
->spi_msg
);
96 *value
= be16_to_cpu(st
->spi_msg
);
101 static int ad5593r_gpio_read(struct ad5592r_state
*st
, u8
*value
)
105 ret
= ad5592r_reg_write(st
, AD5592R_REG_GPIO_IN_EN
,
106 AD5592R_GPIO_READBACK_EN
| st
->gpio_in
);
110 ret
= ad5592r_spi_wnop_r16(st
, &st
->spi_msg
);
114 *value
= (u8
) be16_to_cpu(st
->spi_msg
);
119 static const struct ad5592r_rw_ops ad5592r_rw_ops
= {
120 .write_dac
= ad5592r_write_dac
,
121 .read_adc
= ad5592r_read_adc
,
122 .reg_write
= ad5592r_reg_write
,
123 .reg_read
= ad5592r_reg_read
,
124 .gpio_read
= ad5593r_gpio_read
,
127 static int ad5592r_spi_probe(struct spi_device
*spi
)
129 const struct spi_device_id
*id
= spi_get_device_id(spi
);
131 return ad5592r_probe(&spi
->dev
, id
->name
, &ad5592r_rw_ops
);
134 static int ad5592r_spi_remove(struct spi_device
*spi
)
136 return ad5592r_remove(&spi
->dev
);
139 static const struct spi_device_id ad5592r_spi_ids
[] = {
140 { .name
= "ad5592r", },
143 MODULE_DEVICE_TABLE(spi
, ad5592r_spi_ids
);
145 static const struct of_device_id ad5592r_of_match
[] = {
146 { .compatible
= "adi,ad5592r", },
149 MODULE_DEVICE_TABLE(of
, ad5592r_of_match
);
151 static const struct acpi_device_id ad5592r_acpi_match
[] = {
155 MODULE_DEVICE_TABLE(acpi
, ad5592r_acpi_match
);
157 static struct spi_driver ad5592r_spi_driver
= {
160 .of_match_table
= of_match_ptr(ad5592r_of_match
),
161 .acpi_match_table
= ACPI_PTR(ad5592r_acpi_match
),
163 .probe
= ad5592r_spi_probe
,
164 .remove
= ad5592r_spi_remove
,
165 .id_table
= ad5592r_spi_ids
,
167 module_spi_driver(ad5592r_spi_driver
);
169 MODULE_AUTHOR("Paul Cercueil <paul.cercueil@analog.com>");
170 MODULE_DESCRIPTION("Analog Devices AD5592R multi-channel converters");
171 MODULE_LICENSE("GPL v2");