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>
13 #include <linux/mod_devicetable.h>
14 #include <linux/spi/spi.h>
16 #define AD5592R_GPIO_READBACK_EN BIT(10)
17 #define AD5592R_LDAC_READBACK_EN BIT(6)
19 static int ad5592r_spi_wnop_r16(struct ad5592r_state
*st
, __be16
*buf
)
21 struct spi_device
*spi
= container_of(st
->dev
, struct spi_device
, dev
);
22 struct spi_transfer t
= {
23 .tx_buf
= &st
->spi_msg_nop
,
28 st
->spi_msg_nop
= 0; /* NOP */
30 return spi_sync_transfer(spi
, &t
, 1);
33 static int ad5592r_write_dac(struct ad5592r_state
*st
, unsigned chan
, u16 value
)
35 struct spi_device
*spi
= container_of(st
->dev
, struct spi_device
, dev
);
37 st
->spi_msg
= cpu_to_be16(BIT(15) | (chan
<< 12) | value
);
39 return spi_write(spi
, &st
->spi_msg
, sizeof(st
->spi_msg
));
42 static int ad5592r_read_adc(struct ad5592r_state
*st
, unsigned chan
, u16
*value
)
44 struct spi_device
*spi
= container_of(st
->dev
, struct spi_device
, dev
);
47 st
->spi_msg
= cpu_to_be16((AD5592R_REG_ADC_SEQ
<< 11) | BIT(chan
));
49 ret
= spi_write(spi
, &st
->spi_msg
, sizeof(st
->spi_msg
));
55 * See Figure 40. Single-Channel ADC Conversion Sequence
57 ret
= ad5592r_spi_wnop_r16(st
, &st
->spi_msg
);
61 ret
= ad5592r_spi_wnop_r16(st
, &st
->spi_msg
);
65 *value
= be16_to_cpu(st
->spi_msg
);
70 static int ad5592r_reg_write(struct ad5592r_state
*st
, u8 reg
, u16 value
)
72 struct spi_device
*spi
= container_of(st
->dev
, struct spi_device
, dev
);
74 st
->spi_msg
= cpu_to_be16((reg
<< 11) | value
);
76 return spi_write(spi
, &st
->spi_msg
, sizeof(st
->spi_msg
));
79 static int ad5592r_reg_read(struct ad5592r_state
*st
, u8 reg
, u16
*value
)
81 struct spi_device
*spi
= container_of(st
->dev
, struct spi_device
, dev
);
84 st
->spi_msg
= cpu_to_be16((AD5592R_REG_LDAC
<< 11) |
85 AD5592R_LDAC_READBACK_EN
| (reg
<< 2));
87 ret
= spi_write(spi
, &st
->spi_msg
, sizeof(st
->spi_msg
));
91 ret
= ad5592r_spi_wnop_r16(st
, &st
->spi_msg
);
95 *value
= be16_to_cpu(st
->spi_msg
);
100 static int ad5592r_gpio_read(struct ad5592r_state
*st
, u8
*value
)
104 ret
= ad5592r_reg_write(st
, AD5592R_REG_GPIO_IN_EN
,
105 AD5592R_GPIO_READBACK_EN
| st
->gpio_in
);
109 ret
= ad5592r_spi_wnop_r16(st
, &st
->spi_msg
);
113 *value
= (u8
) be16_to_cpu(st
->spi_msg
);
118 static const struct ad5592r_rw_ops ad5592r_rw_ops
= {
119 .write_dac
= ad5592r_write_dac
,
120 .read_adc
= ad5592r_read_adc
,
121 .reg_write
= ad5592r_reg_write
,
122 .reg_read
= ad5592r_reg_read
,
123 .gpio_read
= ad5592r_gpio_read
,
126 static int ad5592r_spi_probe(struct spi_device
*spi
)
128 const struct spi_device_id
*id
= spi_get_device_id(spi
);
130 return ad5592r_probe(&spi
->dev
, id
->name
, &ad5592r_rw_ops
);
133 static int ad5592r_spi_remove(struct spi_device
*spi
)
135 return ad5592r_remove(&spi
->dev
);
138 static const struct spi_device_id ad5592r_spi_ids
[] = {
139 { .name
= "ad5592r", },
142 MODULE_DEVICE_TABLE(spi
, ad5592r_spi_ids
);
144 static const struct of_device_id ad5592r_of_match
[] = {
145 { .compatible
= "adi,ad5592r", },
148 MODULE_DEVICE_TABLE(of
, ad5592r_of_match
);
150 static const struct acpi_device_id ad5592r_acpi_match
[] = {
154 MODULE_DEVICE_TABLE(acpi
, ad5592r_acpi_match
);
156 static struct spi_driver ad5592r_spi_driver
= {
159 .of_match_table
= ad5592r_of_match
,
160 .acpi_match_table
= ad5592r_acpi_match
,
162 .probe
= ad5592r_spi_probe
,
163 .remove
= ad5592r_spi_remove
,
164 .id_table
= ad5592r_spi_ids
,
166 module_spi_driver(ad5592r_spi_driver
);
168 MODULE_AUTHOR("Paul Cercueil <paul.cercueil@analog.com>");
169 MODULE_DESCRIPTION("Analog Devices AD5592R multi-channel converters");
170 MODULE_LICENSE("GPL v2");