1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Analog Devices AD7091R8 12-bit SAR ADC driver |
4 | * |
5 | * Copyright 2023 Analog Devices Inc. |
6 | */ |
7 | |
8 | #include <linux/bitfield.h> |
9 | #include <linux/iio/iio.h> |
10 | #include <linux/module.h> |
11 | #include <linux/regmap.h> |
12 | #include <linux/gpio/consumer.h> |
13 | #include <linux/spi/spi.h> |
14 | |
15 | #include "ad7091r-base.h" |
16 | |
17 | #define AD7091R8_REG_ADDR_MSK GENMASK(15, 11) |
18 | #define AD7091R8_RD_WR_FLAG_MSK BIT(10) |
19 | #define AD7091R8_REG_DATA_MSK GENMASK(9, 0) |
20 | |
21 | #define AD7091R_SPI_REGMAP_CONFIG(n) { \ |
22 | .reg_bits = 8, \ |
23 | .val_bits = 16, \ |
24 | .volatile_reg = ad7091r_volatile_reg, \ |
25 | .writeable_reg = ad7091r_writeable_reg, \ |
26 | .max_register = AD7091R_REG_CH_HYSTERESIS(n), \ |
27 | } |
28 | |
29 | static int ad7091r8_set_mode(struct ad7091r_state *st, enum ad7091r_mode mode) |
30 | { |
31 | /* AD7091R-2/-4/-8 don't set sample/command/autocycle mode in conf reg */ |
32 | st->mode = mode; |
33 | return 0; |
34 | } |
35 | |
36 | static unsigned int ad7091r8_reg_result_chan_id(unsigned int val) |
37 | { |
38 | return AD7091R8_REG_RESULT_CH_ID(val); |
39 | } |
40 | |
41 | #define AD7091R_SPI_CHIP_INFO(_n, _name) { \ |
42 | .name = _name, \ |
43 | .channels = ad7091r##_n##_channels, \ |
44 | .num_channels = ARRAY_SIZE(ad7091r##_n##_channels), \ |
45 | .vref_mV = 2500, \ |
46 | .reg_result_chan_id = &ad7091r8_reg_result_chan_id, \ |
47 | .set_mode = &ad7091r8_set_mode, \ |
48 | } |
49 | |
50 | #define AD7091R_SPI_CHIP_INFO_IRQ(_n, _name) { \ |
51 | .name = _name, \ |
52 | .channels = ad7091r##_n##_channels_irq, \ |
53 | .num_channels = ARRAY_SIZE(ad7091r##_n##_channels_irq), \ |
54 | .vref_mV = 2500, \ |
55 | .reg_result_chan_id = &ad7091r8_reg_result_chan_id, \ |
56 | .set_mode = &ad7091r8_set_mode, \ |
57 | } |
58 | |
59 | enum ad7091r8_info_ids { |
60 | AD7091R2_INFO, |
61 | AD7091R4_INFO, |
62 | AD7091R4_INFO_IRQ, |
63 | AD7091R8_INFO, |
64 | AD7091R8_INFO_IRQ, |
65 | }; |
66 | |
67 | static const struct iio_chan_spec ad7091r2_channels[] = { |
68 | AD7091R_CHANNEL(0, 12, NULL, 0), |
69 | AD7091R_CHANNEL(1, 12, NULL, 0), |
70 | }; |
71 | |
72 | static const struct iio_chan_spec ad7091r4_channels[] = { |
73 | AD7091R_CHANNEL(0, 12, NULL, 0), |
74 | AD7091R_CHANNEL(1, 12, NULL, 0), |
75 | AD7091R_CHANNEL(2, 12, NULL, 0), |
76 | AD7091R_CHANNEL(3, 12, NULL, 0), |
77 | }; |
78 | |
79 | static const struct iio_chan_spec ad7091r4_channels_irq[] = { |
80 | AD7091R_CHANNEL(0, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)), |
81 | AD7091R_CHANNEL(1, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)), |
82 | AD7091R_CHANNEL(2, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)), |
83 | AD7091R_CHANNEL(3, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)), |
84 | }; |
85 | |
86 | static const struct iio_chan_spec ad7091r8_channels[] = { |
87 | AD7091R_CHANNEL(0, 12, NULL, 0), |
88 | AD7091R_CHANNEL(1, 12, NULL, 0), |
89 | AD7091R_CHANNEL(2, 12, NULL, 0), |
90 | AD7091R_CHANNEL(3, 12, NULL, 0), |
91 | AD7091R_CHANNEL(4, 12, NULL, 0), |
92 | AD7091R_CHANNEL(5, 12, NULL, 0), |
93 | AD7091R_CHANNEL(6, 12, NULL, 0), |
94 | AD7091R_CHANNEL(7, 12, NULL, 0), |
95 | }; |
96 | |
97 | static const struct iio_chan_spec ad7091r8_channels_irq[] = { |
98 | AD7091R_CHANNEL(0, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)), |
99 | AD7091R_CHANNEL(1, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)), |
100 | AD7091R_CHANNEL(2, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)), |
101 | AD7091R_CHANNEL(3, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)), |
102 | AD7091R_CHANNEL(4, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)), |
103 | AD7091R_CHANNEL(5, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)), |
104 | AD7091R_CHANNEL(6, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)), |
105 | AD7091R_CHANNEL(7, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)), |
106 | }; |
107 | |
108 | static void ad7091r_pulse_convst(struct ad7091r_state *st) |
109 | { |
110 | gpiod_set_value_cansleep(desc: st->convst_gpio, value: 1); |
111 | gpiod_set_value_cansleep(desc: st->convst_gpio, value: 0); |
112 | } |
113 | |
114 | static int ad7091r_regmap_bus_reg_read(void *context, unsigned int reg, |
115 | unsigned int *val) |
116 | { |
117 | struct ad7091r_state *st = context; |
118 | struct spi_device *spi = container_of(st->dev, struct spi_device, dev); |
119 | int ret; |
120 | |
121 | struct spi_transfer t[] = { |
122 | { |
123 | .tx_buf = &st->tx_buf, |
124 | .len = 2, |
125 | .cs_change = 1, |
126 | }, { |
127 | .rx_buf = &st->rx_buf, |
128 | .len = 2, |
129 | } |
130 | }; |
131 | |
132 | if (reg == AD7091R_REG_RESULT) |
133 | ad7091r_pulse_convst(st); |
134 | |
135 | st->tx_buf = cpu_to_be16(reg << 11); |
136 | |
137 | ret = spi_sync_transfer(spi, xfers: t, ARRAY_SIZE(t)); |
138 | if (ret < 0) |
139 | return ret; |
140 | |
141 | *val = be16_to_cpu(st->rx_buf); |
142 | return 0; |
143 | } |
144 | |
145 | static int ad7091r_regmap_bus_reg_write(void *context, unsigned int reg, |
146 | unsigned int val) |
147 | { |
148 | struct ad7091r_state *st = context; |
149 | struct spi_device *spi = container_of(st->dev, struct spi_device, dev); |
150 | |
151 | /* |
152 | * AD7091R-2/-4/-8 protocol (datasheet page 31) is to do a single SPI |
153 | * transfer with reg address set in bits B15:B11 and value set in B9:B0. |
154 | */ |
155 | st->tx_buf = cpu_to_be16(FIELD_PREP(AD7091R8_REG_DATA_MSK, val) | |
156 | FIELD_PREP(AD7091R8_RD_WR_FLAG_MSK, 1) | |
157 | FIELD_PREP(AD7091R8_REG_ADDR_MSK, reg)); |
158 | |
159 | return spi_write(spi, buf: &st->tx_buf, len: 2); |
160 | } |
161 | |
162 | static struct regmap_bus ad7091r8_regmap_bus = { |
163 | .reg_read = ad7091r_regmap_bus_reg_read, |
164 | .reg_write = ad7091r_regmap_bus_reg_write, |
165 | .reg_format_endian_default = REGMAP_ENDIAN_BIG, |
166 | .val_format_endian_default = REGMAP_ENDIAN_BIG, |
167 | }; |
168 | |
169 | static const struct ad7091r_chip_info ad7091r8_infos[] = { |
170 | [AD7091R2_INFO] = AD7091R_SPI_CHIP_INFO(2, "ad7091r-2" ), |
171 | [AD7091R4_INFO] = AD7091R_SPI_CHIP_INFO(4, "ad7091r-4" ), |
172 | [AD7091R4_INFO_IRQ] = AD7091R_SPI_CHIP_INFO_IRQ(4, "ad7091r-4" ), |
173 | [AD7091R8_INFO] = AD7091R_SPI_CHIP_INFO(8, "ad7091r-8" ), |
174 | [AD7091R8_INFO_IRQ] = AD7091R_SPI_CHIP_INFO_IRQ(8, "ad7091r-8" ) |
175 | }; |
176 | |
177 | static const struct regmap_config ad7091r2_reg_conf = AD7091R_SPI_REGMAP_CONFIG(2); |
178 | static const struct regmap_config ad7091r4_reg_conf = AD7091R_SPI_REGMAP_CONFIG(4); |
179 | static const struct regmap_config ad7091r8_reg_conf = AD7091R_SPI_REGMAP_CONFIG(8); |
180 | |
181 | static void ad7091r8_regmap_init(struct ad7091r_state *st, |
182 | const struct regmap_config *regmap_conf) |
183 | { |
184 | st->map = devm_regmap_init(st->dev, &ad7091r8_regmap_bus, st, |
185 | regmap_conf); |
186 | } |
187 | |
188 | static int ad7091r8_gpio_setup(struct ad7091r_state *st) |
189 | { |
190 | st->convst_gpio = devm_gpiod_get(dev: st->dev, con_id: "convst" , flags: GPIOD_OUT_LOW); |
191 | if (IS_ERR(ptr: st->convst_gpio)) |
192 | return dev_err_probe(dev: st->dev, err: PTR_ERR(ptr: st->convst_gpio), |
193 | fmt: "Error getting convst GPIO\n" ); |
194 | |
195 | st->reset_gpio = devm_gpiod_get_optional(dev: st->dev, con_id: "reset" , |
196 | flags: GPIOD_OUT_HIGH); |
197 | if (IS_ERR(ptr: st->reset_gpio)) |
198 | return dev_err_probe(dev: st->dev, err: PTR_ERR(ptr: st->reset_gpio), |
199 | fmt: "Error on requesting reset GPIO\n" ); |
200 | |
201 | if (st->reset_gpio) { |
202 | fsleep(usecs: 20); |
203 | gpiod_set_value_cansleep(desc: st->reset_gpio, value: 0); |
204 | } |
205 | |
206 | return 0; |
207 | } |
208 | |
209 | static struct ad7091r_init_info ad7091r2_init_info = { |
210 | .info_no_irq = &ad7091r8_infos[AD7091R2_INFO], |
211 | .regmap_config = &ad7091r2_reg_conf, |
212 | .init_adc_regmap = &ad7091r8_regmap_init, |
213 | .setup = &ad7091r8_gpio_setup |
214 | }; |
215 | |
216 | static struct ad7091r_init_info ad7091r4_init_info = { |
217 | .info_no_irq = &ad7091r8_infos[AD7091R4_INFO], |
218 | .info_irq = &ad7091r8_infos[AD7091R4_INFO_IRQ], |
219 | .regmap_config = &ad7091r4_reg_conf, |
220 | .init_adc_regmap = &ad7091r8_regmap_init, |
221 | .setup = &ad7091r8_gpio_setup |
222 | }; |
223 | |
224 | static struct ad7091r_init_info ad7091r8_init_info = { |
225 | .info_no_irq = &ad7091r8_infos[AD7091R8_INFO], |
226 | .info_irq = &ad7091r8_infos[AD7091R8_INFO_IRQ], |
227 | .regmap_config = &ad7091r8_reg_conf, |
228 | .init_adc_regmap = &ad7091r8_regmap_init, |
229 | .setup = &ad7091r8_gpio_setup |
230 | }; |
231 | |
232 | static int ad7091r8_spi_probe(struct spi_device *spi) |
233 | { |
234 | const struct ad7091r_init_info *init_info; |
235 | |
236 | init_info = spi_get_device_match_data(sdev: spi); |
237 | if (!init_info) |
238 | return -EINVAL; |
239 | |
240 | return ad7091r_probe(dev: &spi->dev, init_info, irq: spi->irq); |
241 | } |
242 | |
243 | static const struct of_device_id ad7091r8_of_match[] = { |
244 | { .compatible = "adi,ad7091r2" , .data = &ad7091r2_init_info }, |
245 | { .compatible = "adi,ad7091r4" , .data = &ad7091r4_init_info }, |
246 | { .compatible = "adi,ad7091r8" , .data = &ad7091r8_init_info }, |
247 | { } |
248 | }; |
249 | MODULE_DEVICE_TABLE(of, ad7091r8_of_match); |
250 | |
251 | static const struct spi_device_id ad7091r8_spi_id[] = { |
252 | { "ad7091r2" , (kernel_ulong_t)&ad7091r2_init_info }, |
253 | { "ad7091r4" , (kernel_ulong_t)&ad7091r4_init_info }, |
254 | { "ad7091r8" , (kernel_ulong_t)&ad7091r8_init_info }, |
255 | { } |
256 | }; |
257 | MODULE_DEVICE_TABLE(spi, ad7091r8_spi_id); |
258 | |
259 | static struct spi_driver ad7091r8_driver = { |
260 | .driver = { |
261 | .name = "ad7091r8" , |
262 | .of_match_table = ad7091r8_of_match, |
263 | }, |
264 | .probe = ad7091r8_spi_probe, |
265 | .id_table = ad7091r8_spi_id, |
266 | }; |
267 | module_spi_driver(ad7091r8_driver); |
268 | |
269 | MODULE_AUTHOR("Marcelo Schmitt <marcelo.schmitt@analog.com>" ); |
270 | MODULE_DESCRIPTION("Analog Devices AD7091R8 ADC driver" ); |
271 | MODULE_LICENSE("GPL" ); |
272 | MODULE_IMPORT_NS(IIO_AD7091R); |
273 | |