2 * AD5592R Digital <-> Analog converters driver
4 * Copyright 2015-2016 Analog Devices Inc.
5 * Author: Paul Cercueil <paul.cercueil@analog.com>
7 * Licensed under the GPL-2.
10 #include "ad5592r-base.h"
12 #include <linux/bitops.h>
13 #include <linux/module.h>
15 #include <linux/spi/spi.h>
16 #include <linux/acpi.h>
18 #define AD5592R_GPIO_READBACK_EN BIT(10)
19 #define AD5592R_LDAC_READBACK_EN BIT(6)
21 static int ad5592r_spi_wnop_r16(struct ad5592r_state
*st
, __be16
*buf
)
23 struct spi_device
*spi
= container_of(st
->dev
, struct spi_device
, dev
);
24 struct spi_transfer t
= {
25 .tx_buf
= &st
->spi_msg_nop
,
30 st
->spi_msg_nop
= 0; /* NOP */
32 return spi_sync_transfer(spi
, &t
, 1);
35 static int ad5592r_write_dac(struct ad5592r_state
*st
, unsigned chan
, u16 value
)
37 struct spi_device
*spi
= container_of(st
->dev
, struct spi_device
, dev
);
39 st
->spi_msg
= cpu_to_be16(BIT(15) | (chan
<< 12) | value
);
41 return spi_write(spi
, &st
->spi_msg
, sizeof(st
->spi_msg
));
44 static int ad5592r_read_adc(struct ad5592r_state
*st
, unsigned chan
, u16
*value
)
46 struct spi_device
*spi
= container_of(st
->dev
, struct spi_device
, dev
);
49 st
->spi_msg
= cpu_to_be16((AD5592R_REG_ADC_SEQ
<< 11) | BIT(chan
));
51 ret
= spi_write(spi
, &st
->spi_msg
, sizeof(st
->spi_msg
));
57 * See Figure 40. Single-Channel ADC Conversion Sequence
59 ret
= ad5592r_spi_wnop_r16(st
, &st
->spi_msg
);
63 ret
= ad5592r_spi_wnop_r16(st
, &st
->spi_msg
);
67 *value
= be16_to_cpu(st
->spi_msg
);
72 static int ad5592r_reg_write(struct ad5592r_state
*st
, u8 reg
, u16 value
)
74 struct spi_device
*spi
= container_of(st
->dev
, struct spi_device
, dev
);
76 st
->spi_msg
= cpu_to_be16((reg
<< 11) | value
);
78 return spi_write(spi
, &st
->spi_msg
, sizeof(st
->spi_msg
));
81 static int ad5592r_reg_read(struct ad5592r_state
*st
, u8 reg
, u16
*value
)
83 struct spi_device
*spi
= container_of(st
->dev
, struct spi_device
, dev
);
86 st
->spi_msg
= cpu_to_be16((AD5592R_REG_LDAC
<< 11) |
87 AD5592R_LDAC_READBACK_EN
| (reg
<< 2));
89 ret
= spi_write(spi
, &st
->spi_msg
, sizeof(st
->spi_msg
));
93 ret
= ad5592r_spi_wnop_r16(st
, &st
->spi_msg
);
97 *value
= be16_to_cpu(st
->spi_msg
);
102 static int ad5593r_gpio_read(struct ad5592r_state
*st
, u8
*value
)
106 ret
= ad5592r_reg_write(st
, AD5592R_REG_GPIO_IN_EN
,
107 AD5592R_GPIO_READBACK_EN
| st
->gpio_in
);
111 ret
= ad5592r_spi_wnop_r16(st
, &st
->spi_msg
);
115 *value
= (u8
) be16_to_cpu(st
->spi_msg
);
120 static const struct ad5592r_rw_ops ad5592r_rw_ops
= {
121 .write_dac
= ad5592r_write_dac
,
122 .read_adc
= ad5592r_read_adc
,
123 .reg_write
= ad5592r_reg_write
,
124 .reg_read
= ad5592r_reg_read
,
125 .gpio_read
= ad5593r_gpio_read
,
128 static int ad5592r_spi_probe(struct spi_device
*spi
)
130 const struct spi_device_id
*id
= spi_get_device_id(spi
);
132 return ad5592r_probe(&spi
->dev
, id
->name
, &ad5592r_rw_ops
);
135 static int ad5592r_spi_remove(struct spi_device
*spi
)
137 return ad5592r_remove(&spi
->dev
);
140 static const struct spi_device_id ad5592r_spi_ids
[] = {
141 { .name
= "ad5592r", },
144 MODULE_DEVICE_TABLE(spi
, ad5592r_spi_ids
);
146 static const struct of_device_id ad5592r_of_match
[] = {
147 { .compatible
= "adi,ad5592r", },
150 MODULE_DEVICE_TABLE(of
, ad5592r_of_match
);
152 static const struct acpi_device_id ad5592r_acpi_match
[] = {
156 MODULE_DEVICE_TABLE(acpi
, ad5592r_acpi_match
);
158 static struct spi_driver ad5592r_spi_driver
= {
161 .of_match_table
= of_match_ptr(ad5592r_of_match
),
162 .acpi_match_table
= ACPI_PTR(ad5592r_acpi_match
),
164 .probe
= ad5592r_spi_probe
,
165 .remove
= ad5592r_spi_remove
,
166 .id_table
= ad5592r_spi_ids
,
168 module_spi_driver(ad5592r_spi_driver
);
170 MODULE_AUTHOR("Paul Cercueil <paul.cercueil@analog.com>");
171 MODULE_DESCRIPTION("Analog Devices AD5592R multi-channel converters");
172 MODULE_LICENSE("GPL v2");