1 /*
2 * Copyright (c) 2023 SILA Embedded Solutions GmbH
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <zephyr/device.h>
7 #include <zephyr/devicetree.h>
8 #include <zephyr/drivers/adc.h>
9 #include <zephyr/drivers/adc/ads1x4s0x.h>
10 #include <zephyr/drivers/spi.h>
11 #include <zephyr/drivers/gpio.h>
12 #include <zephyr/dt-bindings/adc/ads1x4s0x_adc.h>
13 #include <zephyr/logging/log.h>
14 #include <zephyr/kernel.h>
15 #include <zephyr/sys/__assert.h>
16 #include <zephyr/sys/byteorder.h>
17 #include <zephyr/sys/util.h>
18
19 #define ADS1X4S0X_HAS_16_BIT_DEV \
20 (DT_HAS_COMPAT_STATUS_OKAY(ti_ads114s06) || DT_HAS_COMPAT_STATUS_OKAY(ti_ads114s08))
21 #define ADS1X4S0X_HAS_24_BIT_DEV \
22 (DT_HAS_COMPAT_STATUS_OKAY(ti_ads124s06) || DT_HAS_COMPAT_STATUS_OKAY(ti_ads124s08))
23
24 #define ADC_CONTEXT_USES_KERNEL_TIMER 1
25 #define ADC_CONTEXT_WAIT_FOR_COMPLETION_TIMEOUT \
26 K_MSEC(CONFIG_ADC_ADS1X4S0X_WAIT_FOR_COMPLETION_TIMEOUT_MS)
27 #include "adc_context.h"
28
29 LOG_MODULE_REGISTER(ads1x4s0x, CONFIG_ADC_LOG_LEVEL);
30
31 #define ADS1X4S0X_CLK_FREQ_IN_KHZ 4096
32 #define ADS1X4S0X_RESET_LOW_TIME_IN_CLOCK_CYCLES 4
33 #define ADS1X4S0X_START_SYNC_PULSE_DURATION_IN_CLOCK_CYCLES 4
34 #define ADS1X4S0X_SETUP_TIME_IN_CLOCK_CYCLES 32
35 #define ADS1X4S0X_INPUT_SELECTION_AINCOM 12
36 #define ADS1X4S0X_REF_INTERNAL 2500
37 #define ADS1X4S0X_GPIO_MAX 3
38 #define ADS1X4S0X_POWER_ON_RESET_TIME_IN_US 2200
39 #define ADS1X4S0X_VBIAS_PIN_MAX 7
40 #define ADS1X4S0X_VBIAS_PIN_MIN 0
41
42 /* Not mentioned in the datasheet, but instead determined experimentally. */
43 #define ADS1X4S0X_RESET_DELAY_TIME_SAFETY_MARGIN_IN_US 1000
44 #define ADS1X4S0X_RESET_DELAY_TIME_IN_US \
45 (4096 * 1000 / ADS1X4S0X_CLK_FREQ_IN_KHZ + ADS1X4S0X_RESET_DELAY_TIME_SAFETY_MARGIN_IN_US)
46
47 #define ADS1X4S0X_RESET_LOW_TIME_IN_US \
48 (ADS1X4S0X_RESET_LOW_TIME_IN_CLOCK_CYCLES * 1000 / ADS1X4S0X_CLK_FREQ_IN_KHZ)
49 #define ADS1X4S0X_START_SYNC_PULSE_DURATION_IN_US \
50 (ADS1X4S0X_START_SYNC_PULSE_DURATION_IN_CLOCK_CYCLES * 1000 / ADS1X4S0X_CLK_FREQ_IN_KHZ)
51 #define ADS1X4S0X_SETUP_TIME_IN_US \
52 (ADS1X4S0X_SETUP_TIME_IN_CLOCK_CYCLES * 1000 / ADS1X4S0X_CLK_FREQ_IN_KHZ)
53
54 enum ads1x4s0x_command {
55 ADS1X4S0X_COMMAND_NOP = 0x00,
56 ADS1X4S0X_COMMAND_WAKEUP = 0x02,
57 ADS1X4S0X_COMMAND_POWERDOWN = 0x04,
58 ADS1X4S0X_COMMAND_RESET = 0x06,
59 ADS1X4S0X_COMMAND_START = 0x08,
60 ADS1X4S0X_COMMAND_STOP = 0x0A,
61 ADS1X4S0X_COMMAND_SYOCAL = 0x16,
62 ADS1X4S0X_COMMAND_SYGCAL = 0x17,
63 ADS1X4S0X_COMMAND_SFOCAL = 0x19,
64 ADS1X4S0X_COMMAND_RDATA = 0x12,
65 ADS1X4S0X_COMMAND_RREG = 0x20,
66 ADS1X4S0X_COMMAND_WREG = 0x40,
67 };
68
69 enum ads1x4s0x_register {
70 ADS1X4S0X_REGISTER_ID = 0x00,
71 ADS1X4S0X_REGISTER_STATUS = 0x01,
72 ADS1X4S0X_REGISTER_INPMUX = 0x02,
73 ADS1X4S0X_REGISTER_PGA = 0x03,
74 ADS1X4S0X_REGISTER_DATARATE = 0x04,
75 ADS1X4S0X_REGISTER_REF = 0x05,
76 ADS1X4S0X_REGISTER_IDACMAG = 0x06,
77 ADS1X4S0X_REGISTER_IDACMUX = 0x07,
78 ADS1X4S0X_REGISTER_VBIAS = 0x08,
79 ADS1X4S0X_REGISTER_SYS = 0x09,
80 ADS1X4S0X_REGISTER_GPIODAT = 0x10,
81 ADS1X4S0X_REGISTER_GPIOCON = 0x11,
82 ADS114S0X_REGISTER_OFCAL0 = 0x0B,
83 ADS114S0X_REGISTER_OFCAL1 = 0x0C,
84 ADS114S0X_REGISTER_FSCAL0 = 0x0E,
85 ADS114S0X_REGISTER_FSCAL1 = 0x0F,
86 ADS124S0X_REGISTER_OFCAL0 = 0x0A,
87 ADS124S0X_REGISTER_OFCAL1 = 0x0B,
88 ADS124S0X_REGISTER_OFCAL2 = 0x0C,
89 ADS124S0X_REGISTER_FSCAL0 = 0x0E,
90 ADS124S0X_REGISTER_FSCAL1 = 0x0F,
91 ADS124S0X_REGISTER_FSCAL2 = 0x0F,
92 };
93
94 #define ADS1X4S0X_REGISTER_GET_VALUE(value, pos, length) \
95 FIELD_GET(GENMASK(pos + length - 1, pos), value)
96 #define ADS1X4S0X_REGISTER_SET_VALUE(target, value, pos, length) \
97 target &= ~GENMASK(pos + length - 1, pos); \
98 target |= FIELD_PREP(GENMASK(pos + length - 1, pos), value)
99
100 #define ADS1X4S0X_REGISTER_ID_DEV_ID_LENGTH 3
101 #define ADS1X4S0X_REGISTER_ID_DEV_ID_POS 0
102 #define ADS1X4S0X_REGISTER_ID_DEV_ID_GET(value) \
103 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_ID_DEV_ID_POS, \
104 ADS1X4S0X_REGISTER_ID_DEV_ID_LENGTH)
105 #define ADS1X4S0X_REGISTER_ID_DEV_ID_SET(target, value) \
106 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_ID_DEV_ID_POS, \
107 ADS1X4S0X_REGISTER_ID_DEV_ID_LENGTH)
108 #define ADS1X4S0X_REGISTER_STATUS_FL_POR_LENGTH 1
109 #define ADS1X4S0X_REGISTER_STATUS_FL_POR_POS 7
110 #define ADS1X4S0X_REGISTER_STATUS_FL_POR_GET(value) \
111 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_STATUS_FL_POR_POS, \
112 ADS1X4S0X_REGISTER_STATUS_FL_POR_LENGTH)
113 #define ADS1X4S0X_REGISTER_STATUS_FL_POR_SET(target, value) \
114 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_STATUS_FL_POR_POS, \
115 ADS1X4S0X_REGISTER_STATUS_FL_POR_LENGTH)
116 #define ADS1X4S0X_REGISTER_STATUS_NOT_RDY_LENGTH 1
117 #define ADS1X4S0X_REGISTER_STATUS_NOT_RDY_POS 6
118 #define ADS1X4S0X_REGISTER_STATUS_NOT_RDY_GET(value) \
119 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_STATUS_NOT_RDY_POS, \
120 ADS1X4S0X_REGISTER_STATUS_NOT_RDY_LENGTH)
121 #define ADS1X4S0X_REGISTER_STATUS_NOT_RDY_SET(target, value) \
122 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_STATUS_NOT_RDY_POS, \
123 ADS1X4S0X_REGISTER_STATUS_NOT_RDY_LENGTH)
124 #define ADS1X4S0X_REGISTER_STATUS_FL_P_RAILP_LENGTH 1
125 #define ADS1X4S0X_REGISTER_STATUS_FL_P_RAILP_POS 5
126 #define ADS1X4S0X_REGISTER_STATUS_FL_P_RAILP_GET(value) \
127 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_STATUS_FL_P_RAILP_POS, \
128 ADS1X4S0X_REGISTER_STATUS_FL_P_RAILP_LENGTH)
129 #define ADS1X4S0X_REGISTER_STATUS_FL_P_RAILP_SET(target, value) \
130 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_STATUS_FL_P_RAILP_POS, \
131 ADS1X4S0X_REGISTER_STATUS_FL_P_RAILP_LENGTH)
132 #define ADS1X4S0X_REGISTER_STATUS_FL_P_RAILN_LENGTH 1
133 #define ADS1X4S0X_REGISTER_STATUS_FL_P_RAILN_POS 4
134 #define ADS1X4S0X_REGISTER_STATUS_FL_P_RAILN_GET(value) \
135 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_STATUS_FL_P_RAILN_POS, \
136 ADS1X4S0X_REGISTER_STATUS_FL_P_RAILN_LENGTH)
137 #define ADS1X4S0X_REGISTER_STATUS_FL_P_RAILN_SET(target, value) \
138 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_STATUS_FL_P_RAILN_POS, \
139 ADS1X4S0X_REGISTER_STATUS_FL_P_RAILN_LENGTH)
140 #define ADS1X4S0X_REGISTER_STATUS_FL_N_RAILP_LENGTH 1
141 #define ADS1X4S0X_REGISTER_STATUS_FL_N_RAILP_POS 3
142 #define ADS1X4S0X_REGISTER_STATUS_FL_N_RAILP_GET(value) \
143 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_STATUS_FL_N_RAILP_POS, \
144 ADS1X4S0X_REGISTER_STATUS_FL_N_RAILP_LENGTH)
145 #define ADS1X4S0X_REGISTER_STATUS_FL_N_RAILP_SET(target, value) \
146 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_STATUS_FL_N_RAILP_POS, \
147 ADS1X4S0X_REGISTER_STATUS_FL_N_RAILP_LENGTH)
148 #define ADS1X4S0X_REGISTER_STATUS_FL_N_RAILN_LENGTH 1
149 #define ADS1X4S0X_REGISTER_STATUS_FL_N_RAILN_POS 2
150 #define ADS1X4S0X_REGISTER_STATUS_FL_N_RAILN_GET(value) \
151 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_STATUS_FL_N_RAILN_POS, \
152 ADS1X4S0X_REGISTER_STATUS_FL_N_RAILN_LENGTH)
153 #define ADS1X4S0X_REGISTER_STATUS_FL_N_RAILN_SET(target, value) \
154 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_STATUS_FL_N_RAILN_POS, \
155 ADS1X4S0X_REGISTER_STATUS_FL_N_RAILN_LENGTH)
156 #define ADS1X4S0X_REGISTER_STATUS_FL_REF_L1_LENGTH 1
157 #define ADS1X4S0X_REGISTER_STATUS_FL_REF_L1_POS 1
158 #define ADS1X4S0X_REGISTER_STATUS_FL_REF_L1_GET(value) \
159 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_STATUS_FL_REF_L1_POS, \
160 ADS1X4S0X_REGISTER_STATUS_FL_REF_L1_LENGTH)
161 #define ADS1X4S0X_REGISTER_STATUS_FL_REF_L1_SET(target, value) \
162 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_STATUS_FL_REF_L1_POS, \
163 ADS1X4S0X_REGISTER_STATUS_FL_REF_L1_LENGTH)
164 #define ADS1X4S0X_REGISTER_STATUS_FL_REF_L0_LENGTH 1
165 #define ADS1X4S0X_REGISTER_STATUS_FL_REF_L0_POS 0
166 #define ADS1X4S0X_REGISTER_STATUS_FL_REF_L0_GET(value) \
167 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_STATUS_FL_REF_L0_POS, \
168 ADS1X4S0X_REGISTER_STATUS_FL_REF_L0_LENGTH)
169 #define ADS1X4S0X_REGISTER_STATUS_FL_REF_L0_SET(target, value) \
170 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_STATUS_FL_REF_L0_POS, \
171 ADS1X4S0X_REGISTER_STATUS_FL_REF_L0_LENGTH)
172 #define ADS1X4S0X_REGISTER_INPMUX_MUXP_LENGTH 4
173 #define ADS1X4S0X_REGISTER_INPMUX_MUXP_POS 4
174 #define ADS1X4S0X_REGISTER_INPMUX_MUXP_GET(value) \
175 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_INPMUX_MUXP_POS, \
176 ADS1X4S0X_REGISTER_INPMUX_MUXP_LENGTH)
177 #define ADS1X4S0X_REGISTER_INPMUX_MUXP_SET(target, value) \
178 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_INPMUX_MUXP_POS, \
179 ADS1X4S0X_REGISTER_INPMUX_MUXP_LENGTH)
180 #define ADS1X4S0X_REGISTER_INPMUX_MUXN_LENGTH 4
181 #define ADS1X4S0X_REGISTER_INPMUX_MUXN_POS 0
182 #define ADS1X4S0X_REGISTER_INPMUX_MUXN_GET(value) \
183 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_INPMUX_MUXN_POS, \
184 ADS1X4S0X_REGISTER_INPMUX_MUXN_LENGTH)
185 #define ADS1X4S0X_REGISTER_INPMUX_MUXN_SET(target, value) \
186 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_INPMUX_MUXN_POS, \
187 ADS1X4S0X_REGISTER_INPMUX_MUXN_LENGTH)
188 #define ADS1X4S0X_REGISTER_PGA_DELAY_LENGTH 3
189 #define ADS1X4S0X_REGISTER_PGA_DELAY_POS 5
190 #define ADS1X4S0X_REGISTER_PGA_DELAY_GET(value) \
191 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_PGA_DELAY_POS, \
192 ADS1X4S0X_REGISTER_PGA_DELAY_LENGTH)
193 #define ADS1X4S0X_REGISTER_PGA_DELAY_SET(target, value) \
194 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_PGA_DELAY_POS, \
195 ADS1X4S0X_REGISTER_PGA_DELAY_LENGTH)
196 #define ADS1X4S0X_REGISTER_PGA_PGA_EN_LENGTH 2
197 #define ADS1X4S0X_REGISTER_PGA_PGA_EN_POS 3
198 #define ADS1X4S0X_REGISTER_PGA_PGA_EN_GET(value) \
199 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_PGA_PGA_EN_POS, \
200 ADS1X4S0X_REGISTER_PGA_PGA_EN_LENGTH)
201 #define ADS1X4S0X_REGISTER_PGA_PGA_EN_SET(target, value) \
202 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_PGA_PGA_EN_POS, \
203 ADS1X4S0X_REGISTER_PGA_PGA_EN_LENGTH)
204 #define ADS1X4S0X_REGISTER_PGA_GAIN_LENGTH 3
205 #define ADS1X4S0X_REGISTER_PGA_GAIN_POS 0
206 #define ADS1X4S0X_REGISTER_PGA_GAIN_GET(value) \
207 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_PGA_GAIN_POS, \
208 ADS1X4S0X_REGISTER_PGA_GAIN_LENGTH)
209 #define ADS1X4S0X_REGISTER_PGA_GAIN_SET(target, value) \
210 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_PGA_GAIN_POS, \
211 ADS1X4S0X_REGISTER_PGA_GAIN_LENGTH)
212 #define ADS1X4S0X_REGISTER_DATARATE_G_CHOP_LENGTH 1
213 #define ADS1X4S0X_REGISTER_DATARATE_G_CHOP_POS 7
214 #define ADS1X4S0X_REGISTER_DATARATE_G_CHOP_GET(value) \
215 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_DATARATE_G_CHOP_POS, \
216 ADS1X4S0X_REGISTER_DATARATE_G_CHOP_LENGTH)
217 #define ADS1X4S0X_REGISTER_DATARATE_G_CHOP_SET(target, value) \
218 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_DATARATE_G_CHOP_POS, \
219 ADS1X4S0X_REGISTER_DATARATE_G_CHOP_LENGTH)
220 #define ADS1X4S0X_REGISTER_DATARATE_CLK_LENGTH 1
221 #define ADS1X4S0X_REGISTER_DATARATE_CLK_POS 6
222 #define ADS1X4S0X_REGISTER_DATARATE_CLK_GET(value) \
223 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_DATARATE_CLK_POS, \
224 ADS1X4S0X_REGISTER_DATARATE_CLK_LENGTH)
225 #define ADS1X4S0X_REGISTER_DATARATE_CLK_SET(target, value) \
226 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_DATARATE_CLK_POS, \
227 ADS1X4S0X_REGISTER_DATARATE_CLK_LENGTH)
228 #define ADS1X4S0X_REGISTER_DATARATE_MODE_LENGTH 1
229 #define ADS1X4S0X_REGISTER_DATARATE_MODE_POS 5
230 #define ADS1X4S0X_REGISTER_DATARATE_MODE_GET(value) \
231 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_DATARATE_MODE_POS, \
232 ADS1X4S0X_REGISTER_DATARATE_MODE_LENGTH)
233 #define ADS1X4S0X_REGISTER_DATARATE_MODE_SET(target, value) \
234 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_DATARATE_MODE_POS, \
235 ADS1X4S0X_REGISTER_DATARATE_MODE_LENGTH)
236 #define ADS1X4S0X_REGISTER_DATARATE_FILTER_LENGTH 1
237 #define ADS1X4S0X_REGISTER_DATARATE_FILTER_POS 4
238 #define ADS1X4S0X_REGISTER_DATARATE_FILTER_GET(value) \
239 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_DATARATE_FILTER_POS, \
240 ADS1X4S0X_REGISTER_DATARATE_FILTER_LENGTH)
241 #define ADS1X4S0X_REGISTER_DATARATE_FILTER_SET(target, value) \
242 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_DATARATE_FILTER_POS, \
243 ADS1X4S0X_REGISTER_DATARATE_FILTER_LENGTH)
244 #define ADS1X4S0X_REGISTER_DATARATE_DR_LENGTH 4
245 #define ADS1X4S0X_REGISTER_DATARATE_DR_POS 0
246 #define ADS1X4S0X_REGISTER_DATARATE_DR_GET(value) \
247 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_DATARATE_DR_POS, \
248 ADS1X4S0X_REGISTER_DATARATE_DR_LENGTH)
249 #define ADS1X4S0X_REGISTER_DATARATE_DR_SET(target, value) \
250 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_DATARATE_DR_POS, \
251 ADS1X4S0X_REGISTER_DATARATE_DR_LENGTH)
252 #define ADS1X4S0X_REGISTER_REF_FL_REF_EN_LENGTH 2
253 #define ADS1X4S0X_REGISTER_REF_FL_REF_EN_POS 6
254 #define ADS1X4S0X_REGISTER_REF_FL_REF_EN_GET(value) \
255 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_REF_FL_REF_EN_POS, \
256 ADS1X4S0X_REGISTER_REF_FL_REF_EN_LENGTH)
257 #define ADS1X4S0X_REGISTER_REF_FL_REF_EN_SET(target, value) \
258 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_REF_FL_REF_EN_POS, \
259 ADS1X4S0X_REGISTER_REF_FL_REF_EN_LENGTH)
260 #define ADS1X4S0X_REGISTER_REF_NOT_REFP_BUF_LENGTH 1
261 #define ADS1X4S0X_REGISTER_REF_NOT_REFP_BUF_POS 5
262 #define ADS1X4S0X_REGISTER_REF_NOT_REFP_BUF_GET(value) \
263 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_REF_NOT_REFP_BUF_POS, \
264 ADS1X4S0X_REGISTER_REF_NOT_REFP_BUF_LENGTH)
265 #define ADS1X4S0X_REGISTER_REF_NOT_REFP_BUF_SET(target, value) \
266 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_REF_NOT_REFP_BUF_POS, \
267 ADS1X4S0X_REGISTER_REF_NOT_REFP_BUF_LENGTH)
268 #define ADS1X4S0X_REGISTER_REF_NOT_REFN_BUF_LENGTH 1
269 #define ADS1X4S0X_REGISTER_REF_NOT_REFN_BUF_POS 4
270 #define ADS1X4S0X_REGISTER_REF_NOT_REFN_BUF_GET(value) \
271 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_REF_NOT_REFN_BUF_POS, \
272 ADS1X4S0X_REGISTER_REF_NOT_REFN_BUF_LENGTH)
273 #define ADS1X4S0X_REGISTER_REF_NOT_REFN_BUF_SET(target, value) \
274 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_REF_NOT_REFN_BUF_POS, \
275 ADS1X4S0X_REGISTER_REF_NOT_REFN_BUF_LENGTH)
276 #define ADS1X4S0X_REGISTER_REF_REFSEL_LENGTH 2
277 #define ADS1X4S0X_REGISTER_REF_REFSEL_POS 2
278 #define ADS1X4S0X_REGISTER_REF_REFSEL_GET(value) \
279 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_REF_REFSEL_POS, \
280 ADS1X4S0X_REGISTER_REF_REFSEL_LENGTH)
281 #define ADS1X4S0X_REGISTER_REF_REFSEL_SET(target, value) \
282 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_REF_REFSEL_POS, \
283 ADS1X4S0X_REGISTER_REF_REFSEL_LENGTH)
284 #define ADS1X4S0X_REGISTER_REF_REFCON_LENGTH 2
285 #define ADS1X4S0X_REGISTER_REF_REFCON_POS 0
286 #define ADS1X4S0X_REGISTER_REF_REFCON_GET(value) \
287 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_REF_REFCON_POS, \
288 ADS1X4S0X_REGISTER_REF_REFCON_LENGTH)
289 #define ADS1X4S0X_REGISTER_REF_REFCON_SET(target, value) \
290 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_REF_REFCON_POS, \
291 ADS1X4S0X_REGISTER_REF_REFCON_LENGTH)
292 #define ADS1X4S0X_REGISTER_IDACMAG_FL_RAIL_EN_LENGTH 1
293 #define ADS1X4S0X_REGISTER_IDACMAG_FL_RAIL_EN_POS 7
294 #define ADS1X4S0X_REGISTER_IDACMAG_FL_RAIL_EN_GET(value) \
295 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_IDACMAG_FL_RAIL_EN_POS, \
296 ADS1X4S0X_REGISTER_IDACMAG_FL_RAIL_EN_LENGTH)
297 #define ADS1X4S0X_REGISTER_IDACMAG_FL_RAIL_EN_SET(target, value) \
298 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_IDACMAG_FL_RAIL_EN_POS, \
299 ADS1X4S0X_REGISTER_IDACMAG_FL_RAIL_EN_LENGTH)
300 #define ADS1X4S0X_REGISTER_IDACMAG_PSW_LENGTH 1
301 #define ADS1X4S0X_REGISTER_IDACMAG_PSW_POS 6
302 #define ADS1X4S0X_REGISTER_IDACMAG_PSW_GET(value) \
303 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_IDACMAG_PSW_POS, \
304 ADS1X4S0X_REGISTER_IDACMAG_PSW_LENGTH)
305 #define ADS1X4S0X_REGISTER_IDACMAG_PSW_SET(target, value) \
306 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_IDACMAG_PSW_POS, \
307 ADS1X4S0X_REGISTER_IDACMAG_PSW_LENGTH)
308 #define ADS1X4S0X_REGISTER_IDACMAG_IMAG_LENGTH 4
309 #define ADS1X4S0X_REGISTER_IDACMAG_IMAG_POS 0
310 #define ADS1X4S0X_REGISTER_IDACMAG_IMAG_GET(value) \
311 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_IDACMAG_IMAG_POS, \
312 ADS1X4S0X_REGISTER_IDACMAG_IMAG_LENGTH)
313 #define ADS1X4S0X_REGISTER_IDACMAG_IMAG_SET(target, value) \
314 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_IDACMAG_IMAG_POS, \
315 ADS1X4S0X_REGISTER_IDACMAG_IMAG_LENGTH)
316 #define ADS1X4S0X_REGISTER_IDACMUX_I2MUX_LENGTH 4
317 #define ADS1X4S0X_REGISTER_IDACMUX_I2MUX_POS 4
318 #define ADS1X4S0X_REGISTER_IDACMUX_I2MUX_GET(value) \
319 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_IDACMUX_I2MUX_POS, \
320 ADS1X4S0X_REGISTER_IDACMUX_I2MUX_LENGTH)
321 #define ADS1X4S0X_REGISTER_IDACMUX_I2MUX_SET(target, value) \
322 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_IDACMUX_I2MUX_POS, \
323 ADS1X4S0X_REGISTER_IDACMUX_I2MUX_LENGTH)
324 #define ADS1X4S0X_REGISTER_IDACMUX_I1MUX_LENGTH 4
325 #define ADS1X4S0X_REGISTER_IDACMUX_I1MUX_POS 0
326 #define ADS1X4S0X_REGISTER_IDACMUX_I1MUX_GET(value) \
327 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_IDACMUX_I1MUX_POS, \
328 ADS1X4S0X_REGISTER_IDACMUX_I1MUX_LENGTH)
329 #define ADS1X4S0X_REGISTER_IDACMUX_I1MUX_SET(target, value) \
330 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_IDACMUX_I1MUX_POS, \
331 ADS1X4S0X_REGISTER_IDACMUX_I1MUX_LENGTH)
332 #define ADS1X4S0X_REGISTER_VBIAS_VB_LEVEL_LENGTH 1
333 #define ADS1X4S0X_REGISTER_VBIAS_VB_LEVEL_POS 7
334 #define ADS1X4S0X_REGISTER_VBIAS_VB_LEVEL_GET(value) \
335 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_VBIAS_VB_LEVEL_POS, \
336 ADS1X4S0X_REGISTER_VBIAS_VB_LEVEL_LENGTH)
337 #define ADS1X4S0X_REGISTER_VBIAS_VB_LEVEL_SET(target, value) \
338 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_VBIAS_VB_LEVEL_POS, \
339 ADS1X4S0X_REGISTER_VBIAS_VB_LEVEL_LENGTH)
340 #define ADS1X4S0X_REGISTER_GPIODAT_DIR_LENGTH 4
341 #define ADS1X4S0X_REGISTER_GPIODAT_DIR_POS 4
342 #define ADS1X4S0X_REGISTER_GPIODAT_DIR_GET(value) \
343 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_GPIODAT_DIR_POS, \
344 ADS1X4S0X_REGISTER_GPIODAT_DIR_LENGTH)
345 #define ADS1X4S0X_REGISTER_GPIODAT_DIR_SET(target, value) \
346 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_GPIODAT_DIR_POS, \
347 ADS1X4S0X_REGISTER_GPIODAT_DIR_LENGTH)
348 #define ADS1X4S0X_REGISTER_GPIODAT_DAT_LENGTH 4
349 #define ADS1X4S0X_REGISTER_GPIODAT_DAT_POS 0
350 #define ADS1X4S0X_REGISTER_GPIODAT_DAT_GET(value) \
351 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_GPIODAT_DAT_POS, \
352 ADS1X4S0X_REGISTER_GPIODAT_DAT_LENGTH)
353 #define ADS1X4S0X_REGISTER_GPIODAT_DAT_SET(target, value) \
354 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_GPIODAT_DAT_POS, \
355 ADS1X4S0X_REGISTER_GPIODAT_DAT_LENGTH)
356 #define ADS1X4S0X_REGISTER_GPIOCON_CON_LENGTH 4
357 #define ADS1X4S0X_REGISTER_GPIOCON_CON_POS 0
358 #define ADS1X4S0X_REGISTER_GPIOCON_CON_GET(value) \
359 ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_GPIOCON_CON_POS, \
360 ADS1X4S0X_REGISTER_GPIOCON_CON_LENGTH)
361 #define ADS1X4S0X_REGISTER_GPIOCON_CON_SET(target, value) \
362 ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_GPIOCON_CON_POS, \
363 ADS1X4S0X_REGISTER_GPIOCON_CON_LENGTH)
364
365 /*
366 * - AIN0 as positive input
367 * - AIN1 as negative input
368 */
369 #define ADS1X4S0X_REGISTER_INPMUX_SET_DEFAULTS(target) \
370 ADS1X4S0X_REGISTER_INPMUX_MUXP_SET(target, 0b0000); \
371 ADS1X4S0X_REGISTER_INPMUX_MUXN_SET(target, 0b0001)
372 /*
373 * - disable reference monitor
374 * - enable positive reference buffer
375 * - disable negative reference buffer
376 * - use internal reference
377 * - enable internal voltage reference
378 */
379 #define ADS1X4S0X_REGISTER_REF_SET_DEFAULTS(target) \
380 ADS1X4S0X_REGISTER_REF_FL_REF_EN_SET(target, 0b00); \
381 ADS1X4S0X_REGISTER_REF_NOT_REFP_BUF_SET(target, 0b0); \
382 ADS1X4S0X_REGISTER_REF_NOT_REFN_BUF_SET(target, 0b1); \
383 ADS1X4S0X_REGISTER_REF_REFSEL_SET(target, 0b10); \
384 ADS1X4S0X_REGISTER_REF_REFCON_SET(target, 0b01)
385 /*
386 * - disable global chop
387 * - use internal oscillator
388 * - single shot conversion mode
389 * - low latency filter
390 * - 20 samples per second
391 */
392 #define ADS1X4S0X_REGISTER_DATARATE_SET_DEFAULTS(target) \
393 ADS1X4S0X_REGISTER_DATARATE_G_CHOP_SET(target, 0b0); \
394 ADS1X4S0X_REGISTER_DATARATE_CLK_SET(target, 0b0); \
395 ADS1X4S0X_REGISTER_DATARATE_MODE_SET(target, 0b1); \
396 ADS1X4S0X_REGISTER_DATARATE_FILTER_SET(target, 0b1); \
397 ADS1X4S0X_REGISTER_DATARATE_DR_SET(target, 0b0100)
398 /*
399 * - delay of 14*t_mod
400 * - disable gain
401 * - gain 1
402 */
403 #define ADS1X4S0X_REGISTER_PGA_SET_DEFAULTS(target) \
404 ADS1X4S0X_REGISTER_PGA_DELAY_SET(target, 0b000); \
405 ADS1X4S0X_REGISTER_PGA_PGA_EN_SET(target, 0b00); \
406 ADS1X4S0X_REGISTER_PGA_GAIN_SET(target, 0b000)
407 /*
408 * - disable PGA output rail flag
409 * - low-side power switch
410 * - IDAC off
411 */
412 #define ADS1X4S0X_REGISTER_IDACMAG_SET_DEFAULTS(target) \
413 ADS1X4S0X_REGISTER_IDACMAG_FL_RAIL_EN_SET(target, 0b0); \
414 ADS1X4S0X_REGISTER_IDACMAG_PSW_SET(target, 0b0); \
415 ADS1X4S0X_REGISTER_IDACMAG_IMAG_SET(target, 0b0000)
416 /*
417 * - disconnect IDAC1
418 * - disconnect IDAC2
419 */
420 #define ADS1X4S0X_REGISTER_IDACMUX_SET_DEFAULTS(target) \
421 ADS1X4S0X_REGISTER_IDACMUX_I1MUX_SET(target, 0b1111); \
422 ADS1X4S0X_REGISTER_IDACMUX_I2MUX_SET(target, 0b1111)
423
424 struct ads1x4s0x_config {
425 struct spi_dt_spec bus;
426 #if CONFIG_ADC_ASYNC
427 k_thread_stack_t *stack;
428 #endif
429 const struct gpio_dt_spec gpio_reset;
430 const struct gpio_dt_spec gpio_data_ready;
431 const struct gpio_dt_spec gpio_start_sync;
432 int idac_current;
433 uint8_t vbias_level;
434 uint8_t channels;
435 uint8_t resolution;
436 };
437
438 struct ads1x4s0x_data {
439 struct adc_context ctx;
440 #if CONFIG_ADC_ASYNC
441 struct k_thread thread;
442 #endif /* CONFIG_ADC_ASYNC */
443 struct gpio_callback callback_data_ready;
444 struct k_sem data_ready_signal;
445 struct k_sem acquire_signal;
446 void *buffer;
447 void *buffer_ptr;
448 #if CONFIG_ADC_ADS1X4S0X_GPIO
449 struct k_mutex gpio_lock;
450 uint8_t gpio_enabled; /* one bit per GPIO, 1 = enabled */
451 uint8_t gpio_direction; /* one bit per GPIO, 1 = input */
452 uint8_t gpio_value; /* one bit per GPIO, 1 = high */
453 #endif /* CONFIG_ADC_ADS1X4S0X_GPIO */
454 };
455
ads1x4s0x_data_ready_handler(const struct device * dev,struct gpio_callback * gpio_cb,uint32_t pins)456 static void ads1x4s0x_data_ready_handler(const struct device *dev, struct gpio_callback *gpio_cb,
457 uint32_t pins)
458 {
459 ARG_UNUSED(dev);
460 ARG_UNUSED(pins);
461
462 struct ads1x4s0x_data *data =
463 CONTAINER_OF(gpio_cb, struct ads1x4s0x_data, callback_data_ready);
464
465 k_sem_give(&data->data_ready_signal);
466 }
467
ads1x4s0x_read_register(const struct device * dev,enum ads1x4s0x_register register_address,uint8_t * value)468 static int ads1x4s0x_read_register(const struct device *dev,
469 enum ads1x4s0x_register register_address, uint8_t *value)
470 {
471 const struct ads1x4s0x_config *config = dev->config;
472 uint8_t buffer_tx[3];
473 uint8_t buffer_rx[ARRAY_SIZE(buffer_tx)];
474 const struct spi_buf tx_buf[] = {{
475 .buf = buffer_tx,
476 .len = ARRAY_SIZE(buffer_tx),
477 }};
478 const struct spi_buf rx_buf[] = {{
479 .buf = buffer_rx,
480 .len = ARRAY_SIZE(buffer_rx),
481 }};
482 const struct spi_buf_set tx = {
483 .buffers = tx_buf,
484 .count = ARRAY_SIZE(tx_buf),
485 };
486 const struct spi_buf_set rx = {
487 .buffers = rx_buf,
488 .count = ARRAY_SIZE(rx_buf),
489 };
490
491 buffer_tx[0] = ((uint8_t)ADS1X4S0X_COMMAND_RREG) | ((uint8_t)register_address);
492 /* read one register */
493 buffer_tx[1] = 0x00;
494
495 int result = spi_transceive_dt(&config->bus, &tx, &rx);
496
497 if (result != 0) {
498 LOG_ERR("%s: spi_transceive failed with error %i", dev->name, result);
499 return result;
500 }
501
502 *value = buffer_rx[2];
503 LOG_DBG("%s: read from register 0x%02X value 0x%02X", dev->name, register_address, *value);
504
505 return 0;
506 }
507
ads1x4s0x_write_register(const struct device * dev,enum ads1x4s0x_register register_address,uint8_t value)508 static int ads1x4s0x_write_register(const struct device *dev,
509 enum ads1x4s0x_register register_address, uint8_t value)
510 {
511 const struct ads1x4s0x_config *config = dev->config;
512 uint8_t buffer_tx[3];
513 const struct spi_buf tx_buf[] = {{
514 .buf = buffer_tx,
515 .len = ARRAY_SIZE(buffer_tx),
516 }};
517 const struct spi_buf_set tx = {
518 .buffers = tx_buf,
519 .count = ARRAY_SIZE(tx_buf),
520 };
521
522 buffer_tx[0] = ((uint8_t)ADS1X4S0X_COMMAND_WREG) | ((uint8_t)register_address);
523 /* write one register */
524 buffer_tx[1] = 0x00;
525 buffer_tx[2] = value;
526
527 LOG_DBG("%s: writing to register 0x%02X value 0x%02X", dev->name, register_address, value);
528 int result = spi_write_dt(&config->bus, &tx);
529
530 if (result != 0) {
531 LOG_ERR("%s: spi_write failed with error %i", dev->name, result);
532 return result;
533 }
534
535 return 0;
536 }
537
ads1x4s0x_write_multiple_registers(const struct device * dev,enum ads1x4s0x_register * register_addresses,uint8_t * values,size_t count)538 static int ads1x4s0x_write_multiple_registers(const struct device *dev,
539 enum ads1x4s0x_register *register_addresses,
540 uint8_t *values, size_t count)
541 {
542 const struct ads1x4s0x_config *config = dev->config;
543 uint8_t buffer_tx[2];
544 const struct spi_buf tx_buf[] = {
545 {
546 .buf = buffer_tx,
547 .len = ARRAY_SIZE(buffer_tx),
548 },
549 {
550 .buf = values,
551 .len = count,
552 },
553 };
554 const struct spi_buf_set tx = {
555 .buffers = tx_buf,
556 .count = ARRAY_SIZE(tx_buf),
557 };
558
559 if (count == 0) {
560 LOG_WRN("%s: ignoring the command to write 0 registers", dev->name);
561 return -EINVAL;
562 }
563
564 buffer_tx[0] = ((uint8_t)ADS1X4S0X_COMMAND_WREG) | ((uint8_t)register_addresses[0]);
565 buffer_tx[1] = count - 1;
566
567 LOG_HEXDUMP_DBG(register_addresses, count, "writing to registers");
568 LOG_HEXDUMP_DBG(values, count, "values");
569
570 /* ensure that the register addresses are in the correct order */
571 for (size_t i = 1; i < count; ++i) {
572 __ASSERT(register_addresses[i - 1] + 1 == register_addresses[i],
573 "register addresses are not consecutive");
574 }
575
576 int result = spi_write_dt(&config->bus, &tx);
577
578 if (result != 0) {
579 LOG_ERR("%s: spi_write failed with error %i", dev->name, result);
580 return result;
581 }
582
583 return 0;
584 }
585
ads1x4s0x_send_command(const struct device * dev,enum ads1x4s0x_command command)586 static int ads1x4s0x_send_command(const struct device *dev, enum ads1x4s0x_command command)
587 {
588 const struct ads1x4s0x_config *config = dev->config;
589 uint8_t buffer_tx[1];
590 const struct spi_buf tx_buf[] = {{
591 .buf = buffer_tx,
592 .len = ARRAY_SIZE(buffer_tx),
593 }};
594 const struct spi_buf_set tx = {
595 .buffers = tx_buf,
596 .count = ARRAY_SIZE(tx_buf),
597 };
598
599 buffer_tx[0] = (uint8_t)command;
600
601 LOG_DBG("%s: sending command 0x%02X", dev->name, command);
602 int result = spi_write_dt(&config->bus, &tx);
603
604 if (result != 0) {
605 LOG_ERR("%s: spi_write failed with error %i", dev->name, result);
606 return result;
607 }
608
609 return 0;
610 }
611
ads1x4s0x_channel_setup(const struct device * dev,const struct adc_channel_cfg * channel_cfg)612 static int ads1x4s0x_channel_setup(const struct device *dev,
613 const struct adc_channel_cfg *channel_cfg)
614 {
615 const struct ads1x4s0x_config *config = dev->config;
616 uint8_t input_mux = 0;
617 uint8_t reference_control = 0;
618 uint8_t data_rate = 0;
619 uint8_t gain = 0;
620 uint8_t idac_magnitude = 0;
621 uint8_t idac_mux = 0;
622 uint8_t pin_selections[4];
623 uint8_t vbias = 0;
624 size_t pin_selections_size;
625 int result;
626 enum ads1x4s0x_register register_addresses[7];
627 uint8_t values[ARRAY_SIZE(register_addresses)];
628 uint16_t acquisition_time_value = ADC_ACQ_TIME_VALUE(channel_cfg->acquisition_time);
629 uint16_t acquisition_time_unit = ADC_ACQ_TIME_UNIT(channel_cfg->acquisition_time);
630
631 ADS1X4S0X_REGISTER_INPMUX_SET_DEFAULTS(gain);
632 ADS1X4S0X_REGISTER_REF_SET_DEFAULTS(reference_control);
633 ADS1X4S0X_REGISTER_DATARATE_SET_DEFAULTS(data_rate);
634 ADS1X4S0X_REGISTER_PGA_SET_DEFAULTS(gain);
635 ADS1X4S0X_REGISTER_IDACMAG_SET_DEFAULTS(idac_magnitude);
636 ADS1X4S0X_REGISTER_IDACMUX_SET_DEFAULTS(idac_mux);
637
638 if (channel_cfg->channel_id != 0) {
639 LOG_ERR("%s: only one channel is supported", dev->name);
640 return -EINVAL;
641 }
642
643 /* The ADS114 uses samples per seconds units with the lowest being 2.5SPS
644 * and with acquisition_time only having 14b for time, this will not fit
645 * within here for microsecond units. Use Tick units and allow the user to
646 * specify the ODR directly.
647 */
648 if (channel_cfg->acquisition_time != ADC_ACQ_TIME_DEFAULT &&
649 acquisition_time_unit != ADC_ACQ_TIME_TICKS) {
650 LOG_ERR("%s: invalid acquisition time %i", dev->name,
651 channel_cfg->acquisition_time);
652 return -EINVAL;
653 }
654
655 if (channel_cfg->acquisition_time == ADC_ACQ_TIME_DEFAULT) {
656 ADS1X4S0X_REGISTER_DATARATE_DR_SET(data_rate, ADS1X4S0X_CONFIG_DR_20);
657 } else {
658 ADS1X4S0X_REGISTER_DATARATE_DR_SET(data_rate, acquisition_time_value);
659 }
660
661 switch (channel_cfg->reference) {
662 case ADC_REF_INTERNAL:
663 /* disable negative reference buffer */
664 ADS1X4S0X_REGISTER_REF_NOT_REFN_BUF_SET(reference_control, 0b1);
665 /* disable positive reference buffer */
666 ADS1X4S0X_REGISTER_REF_NOT_REFP_BUF_SET(reference_control, 0b1);
667 /* use internal reference */
668 ADS1X4S0X_REGISTER_REF_REFSEL_SET(reference_control, 0b10);
669 break;
670 case ADC_REF_EXTERNAL0:
671 /* enable negative reference buffer */
672 ADS1X4S0X_REGISTER_REF_NOT_REFN_BUF_SET(reference_control, 0b0);
673 /* enable positive reference buffer */
674 ADS1X4S0X_REGISTER_REF_NOT_REFP_BUF_SET(reference_control, 0b0);
675 /* use external reference 0*/
676 ADS1X4S0X_REGISTER_REF_REFSEL_SET(reference_control, 0b00);
677 break;
678 case ADC_REF_EXTERNAL1:
679 /* enable negative reference buffer */
680 ADS1X4S0X_REGISTER_REF_NOT_REFN_BUF_SET(reference_control, 0b0);
681 /* enable positive reference buffer */
682 ADS1X4S0X_REGISTER_REF_NOT_REFP_BUF_SET(reference_control, 0b0);
683 /* use external reference 0*/
684 ADS1X4S0X_REGISTER_REF_REFSEL_SET(reference_control, 0b01);
685 break;
686 default:
687 LOG_ERR("%s: reference %i is not supported", dev->name, channel_cfg->reference);
688 return -EINVAL;
689 }
690
691 if (channel_cfg->differential) {
692 LOG_DBG("%s: configuring channel for a differential measurement from the pins (p, "
693 "n) (%i, %i)",
694 dev->name, channel_cfg->input_positive, channel_cfg->input_negative);
695 if (channel_cfg->input_positive >= config->channels &&
696 channel_cfg->input_positive != ADS1X4S0X_INPUT_SELECTION_AINCOM) {
697 LOG_ERR("%s: positive channel input %i is invalid", dev->name,
698 channel_cfg->input_positive);
699 return -EINVAL;
700 }
701
702 if (channel_cfg->input_negative >= config->channels &&
703 channel_cfg->input_negative != ADS1X4S0X_INPUT_SELECTION_AINCOM) {
704 LOG_ERR("%s: negative channel input %i is invalid", dev->name,
705 channel_cfg->input_negative);
706 return -EINVAL;
707 }
708
709 if (channel_cfg->input_positive == channel_cfg->input_negative) {
710 LOG_ERR("%s: negative and positive channel inputs must be different",
711 dev->name);
712 return -EINVAL;
713 }
714
715 ADS1X4S0X_REGISTER_INPMUX_MUXP_SET(input_mux, channel_cfg->input_positive);
716 ADS1X4S0X_REGISTER_INPMUX_MUXN_SET(input_mux, channel_cfg->input_negative);
717 pin_selections[0] = channel_cfg->input_positive;
718 pin_selections[1] = channel_cfg->input_negative;
719 } else {
720 LOG_DBG("%s: configuring channel for single ended measurement from input %i",
721 dev->name, channel_cfg->input_positive);
722 if (channel_cfg->input_positive >= config->channels &&
723 channel_cfg->input_positive != ADS1X4S0X_INPUT_SELECTION_AINCOM) {
724 LOG_ERR("%s: channel input %i is invalid", dev->name,
725 channel_cfg->input_positive);
726 return -EINVAL;
727 }
728
729 ADS1X4S0X_REGISTER_INPMUX_MUXP_SET(input_mux, channel_cfg->input_positive);
730 ADS1X4S0X_REGISTER_INPMUX_MUXN_SET(input_mux, ADS1X4S0X_INPUT_SELECTION_AINCOM);
731 pin_selections[0] = channel_cfg->input_positive;
732 pin_selections[1] = ADS1X4S0X_INPUT_SELECTION_AINCOM;
733 }
734
735 switch (channel_cfg->gain) {
736 case ADC_GAIN_1:
737 /* set gain value */
738 ADS1X4S0X_REGISTER_PGA_GAIN_SET(gain, 0b000);
739 break;
740 case ADC_GAIN_2:
741 ADS1X4S0X_REGISTER_PGA_GAIN_SET(gain, 0b001);
742 break;
743 case ADC_GAIN_4:
744 ADS1X4S0X_REGISTER_PGA_GAIN_SET(gain, 0b010);
745 break;
746 case ADC_GAIN_8:
747 ADS1X4S0X_REGISTER_PGA_GAIN_SET(gain, 0b011);
748 break;
749 case ADC_GAIN_16:
750 ADS1X4S0X_REGISTER_PGA_GAIN_SET(gain, 0b100);
751 break;
752 case ADC_GAIN_32:
753 ADS1X4S0X_REGISTER_PGA_GAIN_SET(gain, 0b101);
754 break;
755 case ADC_GAIN_64:
756 ADS1X4S0X_REGISTER_PGA_GAIN_SET(gain, 0b110);
757 break;
758 case ADC_GAIN_128:
759 ADS1X4S0X_REGISTER_PGA_GAIN_SET(gain, 0b111);
760 break;
761 default:
762 LOG_ERR("%s: gain value %i not supported", dev->name, channel_cfg->gain);
763 return -EINVAL;
764 }
765
766 if (channel_cfg->gain != ADC_GAIN_1) {
767 /* enable gain */
768 ADS1X4S0X_REGISTER_PGA_PGA_EN_SET(gain, 0b01);
769 }
770
771 switch (config->idac_current) {
772 case 0:
773 ADS1X4S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0000);
774 break;
775 case 10:
776 ADS1X4S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0001);
777 break;
778 case 50:
779 ADS1X4S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0010);
780 break;
781 case 100:
782 ADS1X4S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0011);
783 break;
784 case 250:
785 ADS1X4S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0100);
786 break;
787 case 500:
788 ADS1X4S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0101);
789 break;
790 case 750:
791 ADS1X4S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0110);
792 break;
793 case 1000:
794 ADS1X4S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0111);
795 break;
796 case 1500:
797 ADS1X4S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b1000);
798 break;
799 case 2000:
800 ADS1X4S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b1001);
801 break;
802 default:
803 LOG_ERR("%s: IDAC magnitude %i not supported", dev->name, config->idac_current);
804 return -EINVAL;
805 }
806
807 if (channel_cfg->current_source_pin_set) {
808 LOG_DBG("%s: current source pin set to %i and %i", dev->name,
809 channel_cfg->current_source_pin[0], channel_cfg->current_source_pin[1]);
810 if (channel_cfg->current_source_pin[0] > 0b1111) {
811 LOG_ERR("%s: invalid selection %i for I1MUX", dev->name,
812 channel_cfg->current_source_pin[0]);
813 return -EINVAL;
814 }
815
816 if (channel_cfg->current_source_pin[1] > 0b1111) {
817 LOG_ERR("%s: invalid selection %i for I2MUX", dev->name,
818 channel_cfg->current_source_pin[1]);
819 return -EINVAL;
820 }
821
822 ADS1X4S0X_REGISTER_IDACMUX_I1MUX_SET(idac_mux, channel_cfg->current_source_pin[0]);
823 ADS1X4S0X_REGISTER_IDACMUX_I2MUX_SET(idac_mux, channel_cfg->current_source_pin[1]);
824 pin_selections[2] = channel_cfg->current_source_pin[0];
825 pin_selections[3] = channel_cfg->current_source_pin[1];
826 pin_selections_size = 4;
827 } else {
828 LOG_DBG("%s: current source pins not set", dev->name);
829 pin_selections_size = 2;
830 }
831
832 for (size_t i = 0; i < pin_selections_size; ++i) {
833 if (pin_selections[i] > ADS1X4S0X_INPUT_SELECTION_AINCOM) {
834 continue;
835 }
836
837 for (size_t j = i + 1; j < pin_selections_size; ++j) {
838 if (pin_selections[j] > ADS1X4S0X_INPUT_SELECTION_AINCOM) {
839 continue;
840 }
841
842 if (pin_selections[i] == pin_selections[j]) {
843 LOG_ERR("%s: pins for inputs and current sources must be different",
844 dev->name);
845 return -EINVAL;
846 }
847 }
848 }
849
850 ADS1X4S0X_REGISTER_VBIAS_VB_LEVEL_SET(vbias, config->vbias_level);
851
852 if ((channel_cfg->vbias_pins &
853 ~GENMASK(ADS1X4S0X_VBIAS_PIN_MAX, ADS1X4S0X_VBIAS_PIN_MIN)) != 0) {
854 LOG_ERR("%s: invalid VBIAS pin selection 0x%08X", dev->name,
855 channel_cfg->vbias_pins);
856 return -EINVAL;
857 }
858
859 vbias |= channel_cfg->vbias_pins;
860
861 register_addresses[0] = ADS1X4S0X_REGISTER_INPMUX;
862 register_addresses[1] = ADS1X4S0X_REGISTER_PGA;
863 register_addresses[2] = ADS1X4S0X_REGISTER_DATARATE;
864 register_addresses[3] = ADS1X4S0X_REGISTER_REF;
865 register_addresses[4] = ADS1X4S0X_REGISTER_IDACMAG;
866 register_addresses[5] = ADS1X4S0X_REGISTER_IDACMUX;
867 register_addresses[6] = ADS1X4S0X_REGISTER_VBIAS;
868 BUILD_ASSERT(ARRAY_SIZE(register_addresses) == 7);
869 values[0] = input_mux;
870 values[1] = gain;
871 values[2] = data_rate;
872 values[3] = reference_control;
873 values[4] = idac_magnitude;
874 values[5] = idac_mux;
875 values[6] = vbias;
876 BUILD_ASSERT(ARRAY_SIZE(values) == 7);
877
878 result = ads1x4s0x_write_multiple_registers(dev, register_addresses, values,
879 ARRAY_SIZE(values));
880
881 if (result != 0) {
882 LOG_ERR("%s: unable to configure registers", dev->name);
883 return result;
884 }
885
886 return 0;
887 }
888
ads1x4s0x_validate_buffer_size(const struct device * dev,const struct adc_sequence * sequence)889 static int ads1x4s0x_validate_buffer_size(const struct device *dev,
890 const struct adc_sequence *sequence)
891 {
892 const struct ads1x4s0x_config *config = dev->config;
893 size_t needed;
894
895 needed = (config->resolution > 16) ? sizeof(int32_t) : sizeof(int16_t);
896
897 if (sequence->options) {
898 needed *= (1 + sequence->options->extra_samplings);
899 }
900
901 if (sequence->buffer_size < needed) {
902 return -ENOMEM;
903 }
904
905 return 0;
906 }
907
ads1x4s0x_validate_sequence(const struct device * dev,const struct adc_sequence * sequence)908 static int ads1x4s0x_validate_sequence(const struct device *dev,
909 const struct adc_sequence *sequence)
910 {
911 const struct ads1x4s0x_config *config = dev->config;
912
913 if (sequence->resolution != config->resolution) {
914 LOG_ERR("%s: invalid resolution", dev->name);
915 return -EINVAL;
916 }
917
918 if (sequence->channels != BIT(0)) {
919 LOG_ERR("%s: invalid channel", dev->name);
920 return -EINVAL;
921 }
922
923 if (sequence->oversampling) {
924 LOG_ERR("%s: oversampling is not supported", dev->name);
925 return -EINVAL;
926 }
927
928 return ads1x4s0x_validate_buffer_size(dev, sequence);
929 }
930
adc_context_update_buffer_pointer(struct adc_context * ctx,bool repeat_sampling)931 static void adc_context_update_buffer_pointer(struct adc_context *ctx, bool repeat_sampling)
932 {
933 struct ads1x4s0x_data *data = CONTAINER_OF(ctx, struct ads1x4s0x_data, ctx);
934
935 if (repeat_sampling) {
936 data->buffer = data->buffer_ptr;
937 }
938 }
939
adc_context_start_sampling(struct adc_context * ctx)940 static void adc_context_start_sampling(struct adc_context *ctx)
941 {
942 struct ads1x4s0x_data *data = CONTAINER_OF(ctx, struct ads1x4s0x_data, ctx);
943
944 data->buffer_ptr = data->buffer;
945 k_sem_give(&data->acquire_signal);
946 }
947
ads1x4s0x_adc_start_read(const struct device * dev,const struct adc_sequence * sequence,bool wait)948 static int ads1x4s0x_adc_start_read(const struct device *dev, const struct adc_sequence *sequence,
949 bool wait)
950 {
951 int result;
952 struct ads1x4s0x_data *data = dev->data;
953
954 result = ads1x4s0x_validate_sequence(dev, sequence);
955
956 if (result != 0) {
957 LOG_ERR("%s: sequence validation failed", dev->name);
958 return result;
959 }
960
961 data->buffer = sequence->buffer;
962
963 adc_context_start_read(&data->ctx, sequence);
964
965 if (wait) {
966 result = adc_context_wait_for_completion(&data->ctx);
967 }
968
969 return result;
970 }
971
ads1x4s0x_send_start_read(const struct device * dev)972 static int ads1x4s0x_send_start_read(const struct device *dev)
973 {
974 const struct ads1x4s0x_config *config = dev->config;
975 int result;
976
977 if (config->gpio_start_sync.port == 0) {
978 result = ads1x4s0x_send_command(dev, ADS1X4S0X_COMMAND_START);
979 if (result != 0) {
980 LOG_ERR("%s: unable to send START/SYNC command", dev->name);
981 return result;
982 }
983 } else {
984 result = gpio_pin_set_dt(&config->gpio_start_sync, 1);
985
986 if (result != 0) {
987 LOG_ERR("%s: unable to start ADC operation", dev->name);
988 return result;
989 }
990
991 k_sleep(K_USEC(ADS1X4S0X_START_SYNC_PULSE_DURATION_IN_US +
992 ADS1X4S0X_SETUP_TIME_IN_US));
993
994 result = gpio_pin_set_dt(&config->gpio_start_sync, 0);
995
996 if (result != 0) {
997 LOG_ERR("%s: unable to start ADC operation", dev->name);
998 return result;
999 }
1000 }
1001
1002 return 0;
1003 }
1004
ads1x4s0x_wait_data_ready(const struct device * dev)1005 static int ads1x4s0x_wait_data_ready(const struct device *dev)
1006 {
1007 struct ads1x4s0x_data *data = dev->data;
1008
1009 return k_sem_take(&data->data_ready_signal, ADC_CONTEXT_WAIT_FOR_COMPLETION_TIMEOUT);
1010 }
1011
1012 #if ADS1X4S0X_HAS_16_BIT_DEV
ads1x4s0x_read_sample_16(const struct device * dev,int16_t * buffer)1013 static int ads1x4s0x_read_sample_16(const struct device *dev, int16_t *buffer)
1014 {
1015 const struct ads1x4s0x_config *config = dev->config;
1016 uint8_t buffer_tx[3];
1017 uint8_t buffer_rx[ARRAY_SIZE(buffer_tx)];
1018 const struct spi_buf tx_buf[] = {{
1019 .buf = buffer_tx,
1020 .len = 3,
1021 }};
1022 const struct spi_buf rx_buf[] = {{
1023 .buf = buffer_rx,
1024 .len = 3,
1025 }};
1026 const struct spi_buf_set tx = {
1027 .buffers = tx_buf,
1028 .count = ARRAY_SIZE(tx_buf),
1029 };
1030 const struct spi_buf_set rx = {
1031 .buffers = rx_buf,
1032 .count = ARRAY_SIZE(rx_buf),
1033 };
1034
1035 buffer_tx[0] = (uint8_t)ADS1X4S0X_COMMAND_RDATA;
1036
1037 int result = spi_transceive_dt(&config->bus, &tx, &rx);
1038
1039 if (result != 0) {
1040 LOG_ERR("%s: spi_transceive failed with error %i", dev->name, result);
1041 return result;
1042 }
1043
1044 *buffer = sys_get_be16(buffer_rx + 1);
1045 LOG_DBG("%s: read ADC sample %i", dev->name, *buffer);
1046
1047 return 0;
1048 }
1049 #endif
1050
1051 #if ADS1X4S0X_HAS_24_BIT_DEV
ads1x4s0x_read_sample_24(const struct device * dev,int32_t * buffer)1052 static int ads1x4s0x_read_sample_24(const struct device *dev, int32_t *buffer)
1053 {
1054 const struct ads1x4s0x_config *config = dev->config;
1055 uint8_t buffer_tx[5] = {0};
1056 uint8_t buffer_rx[ARRAY_SIZE(buffer_tx)];
1057 const struct spi_buf tx_buf[] = {{
1058 .buf = buffer_tx,
1059 .len = 4,
1060 }};
1061 const struct spi_buf rx_buf[] = {{
1062 .buf = buffer_rx,
1063 .len = 4,
1064 }};
1065 const struct spi_buf_set tx = {
1066 .buffers = tx_buf,
1067 .count = ARRAY_SIZE(tx_buf),
1068 };
1069 const struct spi_buf_set rx = {
1070 .buffers = rx_buf,
1071 .count = ARRAY_SIZE(rx_buf),
1072 };
1073
1074 buffer_tx[0] = (uint8_t)ADS1X4S0X_COMMAND_RDATA;
1075
1076 int result = spi_transceive_dt(&config->bus, &tx, &rx);
1077
1078 if (result != 0) {
1079 LOG_ERR("%s: spi_transceive failed with error %i", dev->name, result);
1080 return result;
1081 }
1082
1083 *buffer = (int32_t)sys_get_be32(buffer_rx + 1) >> 8;
1084
1085 LOG_DBG("%s: read ADC sample 0x%02X%02X%02X", dev->name, *(buffer_rx + 1), *(buffer_rx + 2),
1086 *(buffer_rx + 3));
1087
1088 return 0;
1089 }
1090 #endif
1091
ads1x4s0x_adc_perform_read(const struct device * dev)1092 static int ads1x4s0x_adc_perform_read(const struct device *dev)
1093 {
1094 int result;
1095 const struct ads1x4s0x_config *config = dev->config;
1096 struct ads1x4s0x_data *data = dev->data;
1097 void *buffer = data->buffer;
1098
1099 k_sem_take(&data->acquire_signal, K_FOREVER);
1100 k_sem_reset(&data->data_ready_signal);
1101
1102 result = ads1x4s0x_send_start_read(dev);
1103 if (result != 0) {
1104 LOG_ERR("%s: unable to start ADC conversion", dev->name);
1105 adc_context_complete(&data->ctx, result);
1106 return result;
1107 }
1108
1109 result = ads1x4s0x_wait_data_ready(dev);
1110 if (result != 0) {
1111 LOG_ERR("%s: waiting for data to be ready failed", dev->name);
1112 adc_context_complete(&data->ctx, result);
1113 return result;
1114 }
1115
1116 #if ADS1X4S0X_HAS_24_BIT_DEV
1117 if (config->resolution == 24) {
1118 result = ads1x4s0x_read_sample_24(dev, (int32_t *)data->buffer);
1119
1120 if (result == 0) {
1121 buffer = (int32_t *)buffer + 1;
1122 adc_context_on_sampling_done(&data->ctx, dev);
1123 return 0;
1124 }
1125
1126 }
1127 #endif
1128
1129 #if ADS1X4S0X_HAS_16_BIT_DEV
1130 if (config->resolution == 16) {
1131 result = ads1x4s0x_read_sample_16(dev, (int16_t *)data->buffer);
1132
1133 if (result == 0) {
1134 buffer = (int16_t *)buffer + 1;
1135 adc_context_on_sampling_done(&data->ctx, dev);
1136 return 0;
1137 }
1138
1139 }
1140 #endif
1141
1142 LOG_ERR("%s: reading sample failed", dev->name);
1143 adc_context_complete(&data->ctx, result);
1144 return result;
1145 }
1146
1147 #if CONFIG_ADC_ASYNC
ads1x4s0x_adc_read_async(const struct device * dev,const struct adc_sequence * sequence,struct k_poll_signal * async)1148 static int ads1x4s0x_adc_read_async(const struct device *dev, const struct adc_sequence *sequence,
1149 struct k_poll_signal *async)
1150 {
1151 int result;
1152 struct ads1x4s0x_data *data = dev->data;
1153
1154 adc_context_lock(&data->ctx, true, async);
1155 result = ads1x4s0x_adc_start_read(dev, sequence, true);
1156 adc_context_release(&data->ctx, result);
1157
1158 return result;
1159 }
1160
ads1x4s0x_read(const struct device * dev,const struct adc_sequence * sequence)1161 static int ads1x4s0x_read(const struct device *dev, const struct adc_sequence *sequence)
1162 {
1163 int result;
1164 struct ads1x4s0x_data *data = dev->data;
1165
1166 adc_context_lock(&data->ctx, false, NULL);
1167 result = ads1x4s0x_adc_start_read(dev, sequence, true);
1168 adc_context_release(&data->ctx, result);
1169
1170 return result;
1171 }
1172
1173 #else
ads1x4s0x_read(const struct device * dev,const struct adc_sequence * sequence)1174 static int ads1x4s0x_read(const struct device *dev, const struct adc_sequence *sequence)
1175 {
1176 int result;
1177 struct ads1x4s0x_data *data = dev->data;
1178
1179 adc_context_lock(&data->ctx, false, NULL);
1180 result = ads1x4s0x_adc_start_read(dev, sequence, false);
1181
1182 while (result == 0 && k_sem_take(&data->ctx.sync, K_NO_WAIT) != 0) {
1183 result = ads1x4s0x_adc_perform_read(dev);
1184 }
1185
1186 adc_context_release(&data->ctx, result);
1187 return result;
1188 }
1189 #endif
1190
1191 #if CONFIG_ADC_ASYNC
ads1x4s0x_acquisition_thread(void * p1,void * p2,void * p3)1192 static void ads1x4s0x_acquisition_thread(void *p1, void *p2, void *p3)
1193 {
1194 ARG_UNUSED(p2);
1195 ARG_UNUSED(p3);
1196
1197 const struct device *dev = p1;
1198
1199 while (true) {
1200 ads1x4s0x_adc_perform_read(dev);
1201 }
1202 }
1203 #endif
1204
1205 #ifdef CONFIG_ADC_ADS1X4S0X_GPIO
ads1x4s0x_gpio_write_config(const struct device * dev)1206 static int ads1x4s0x_gpio_write_config(const struct device *dev)
1207 {
1208 struct ads1x4s0x_data *data = dev->data;
1209 enum ads1x4s0x_register register_addresses[2];
1210 uint8_t register_values[ARRAY_SIZE(register_addresses)];
1211 uint8_t gpio_dat = 0;
1212 uint8_t gpio_con = 0;
1213
1214 ADS1X4S0X_REGISTER_GPIOCON_CON_SET(gpio_con, data->gpio_enabled);
1215 ADS1X4S0X_REGISTER_GPIODAT_DAT_SET(gpio_dat, data->gpio_value);
1216 ADS1X4S0X_REGISTER_GPIODAT_DIR_SET(gpio_dat, data->gpio_direction);
1217
1218 register_values[0] = gpio_dat;
1219 register_values[1] = gpio_con;
1220 register_addresses[0] = ADS1X4S0X_REGISTER_GPIODAT;
1221 register_addresses[1] = ADS1X4S0X_REGISTER_GPIOCON;
1222 return ads1x4s0x_write_multiple_registers(dev, register_addresses, register_values,
1223 ARRAY_SIZE(register_values));
1224 }
1225
ads1x4s0x_gpio_write_value(const struct device * dev)1226 static int ads1x4s0x_gpio_write_value(const struct device *dev)
1227 {
1228 struct ads1x4s0x_data *data = dev->data;
1229 uint8_t gpio_dat = 0;
1230
1231 ADS1X4S0X_REGISTER_GPIODAT_DAT_SET(gpio_dat, data->gpio_value);
1232 ADS1X4S0X_REGISTER_GPIODAT_DIR_SET(gpio_dat, data->gpio_direction);
1233
1234 return ads1x4s0x_write_register(dev, ADS1X4S0X_REGISTER_GPIODAT, gpio_dat);
1235 }
1236
ads1x4s0x_gpio_set_output(const struct device * dev,uint8_t pin,bool initial_value)1237 int ads1x4s0x_gpio_set_output(const struct device *dev, uint8_t pin, bool initial_value)
1238 {
1239 struct ads1x4s0x_data *data = dev->data;
1240 int result = 0;
1241
1242 if (pin > ADS1X4S0X_GPIO_MAX) {
1243 LOG_ERR("%s: invalid pin %i", dev->name, pin);
1244 return -EINVAL;
1245 }
1246
1247 k_mutex_lock(&data->gpio_lock, K_FOREVER);
1248
1249 data->gpio_enabled |= BIT(pin);
1250 data->gpio_direction &= ~BIT(pin);
1251
1252 if (initial_value) {
1253 data->gpio_value |= BIT(pin);
1254 } else {
1255 data->gpio_value &= ~BIT(pin);
1256 }
1257
1258 result = ads1x4s0x_gpio_write_config(dev);
1259
1260 k_mutex_unlock(&data->gpio_lock);
1261
1262 return result;
1263 }
1264
ads1x4s0x_gpio_set_input(const struct device * dev,uint8_t pin)1265 int ads1x4s0x_gpio_set_input(const struct device *dev, uint8_t pin)
1266 {
1267 struct ads1x4s0x_data *data = dev->data;
1268 int result = 0;
1269
1270 if (pin > ADS1X4S0X_GPIO_MAX) {
1271 LOG_ERR("%s: invalid pin %i", dev->name, pin);
1272 return -EINVAL;
1273 }
1274
1275 k_mutex_lock(&data->gpio_lock, K_FOREVER);
1276
1277 data->gpio_enabled |= BIT(pin);
1278 data->gpio_direction |= BIT(pin);
1279 data->gpio_value &= ~BIT(pin);
1280
1281 result = ads1x4s0x_gpio_write_config(dev);
1282
1283 k_mutex_unlock(&data->gpio_lock);
1284
1285 return result;
1286 }
1287
ads1x4s0x_gpio_deconfigure(const struct device * dev,uint8_t pin)1288 int ads1x4s0x_gpio_deconfigure(const struct device *dev, uint8_t pin)
1289 {
1290 struct ads1x4s0x_data *data = dev->data;
1291 int result = 0;
1292
1293 if (pin > ADS1X4S0X_GPIO_MAX) {
1294 LOG_ERR("%s: invalid pin %i", dev->name, pin);
1295 return -EINVAL;
1296 }
1297
1298 k_mutex_lock(&data->gpio_lock, K_FOREVER);
1299
1300 data->gpio_enabled &= ~BIT(pin);
1301 data->gpio_direction |= BIT(pin);
1302 data->gpio_value &= ~BIT(pin);
1303
1304 result = ads1x4s0x_gpio_write_config(dev);
1305
1306 k_mutex_unlock(&data->gpio_lock);
1307
1308 return result;
1309 }
1310
ads1x4s0x_gpio_set_pin_value(const struct device * dev,uint8_t pin,bool value)1311 int ads1x4s0x_gpio_set_pin_value(const struct device *dev, uint8_t pin, bool value)
1312 {
1313 struct ads1x4s0x_data *data = dev->data;
1314 int result = 0;
1315
1316 if (pin > ADS1X4S0X_GPIO_MAX) {
1317 LOG_ERR("%s: invalid pin %i", dev->name, pin);
1318 return -EINVAL;
1319 }
1320
1321 k_mutex_lock(&data->gpio_lock, K_FOREVER);
1322
1323 if ((BIT(pin) & data->gpio_enabled) == 0) {
1324 LOG_ERR("%s: gpio pin %i not configured", dev->name, pin);
1325 result = -EINVAL;
1326 } else if ((BIT(pin) & data->gpio_direction) != 0) {
1327 LOG_ERR("%s: gpio pin %i not configured as output", dev->name, pin);
1328 result = -EINVAL;
1329 } else {
1330 data->gpio_value |= BIT(pin);
1331
1332 result = ads1x4s0x_gpio_write_value(dev);
1333 }
1334
1335 k_mutex_unlock(&data->gpio_lock);
1336
1337 return result;
1338 }
1339
ads1x4s0x_gpio_get_pin_value(const struct device * dev,uint8_t pin,bool * value)1340 int ads1x4s0x_gpio_get_pin_value(const struct device *dev, uint8_t pin, bool *value)
1341 {
1342 struct ads1x4s0x_data *data = dev->data;
1343 int result = 0;
1344 uint8_t gpio_dat;
1345
1346 if (pin > ADS1X4S0X_GPIO_MAX) {
1347 LOG_ERR("%s: invalid pin %i", dev->name, pin);
1348 return -EINVAL;
1349 }
1350
1351 k_mutex_lock(&data->gpio_lock, K_FOREVER);
1352
1353 if ((BIT(pin) & data->gpio_enabled) == 0) {
1354 LOG_ERR("%s: gpio pin %i not configured", dev->name, pin);
1355 result = -EINVAL;
1356 } else if ((BIT(pin) & data->gpio_direction) == 0) {
1357 LOG_ERR("%s: gpio pin %i not configured as input", dev->name, pin);
1358 result = -EINVAL;
1359 } else {
1360 result = ads1x4s0x_read_register(dev, ADS1X4S0X_REGISTER_GPIODAT, &gpio_dat);
1361 data->gpio_value = ADS1X4S0X_REGISTER_GPIODAT_DAT_GET(gpio_dat);
1362 *value = (BIT(pin) & data->gpio_value) != 0;
1363 }
1364
1365 k_mutex_unlock(&data->gpio_lock);
1366
1367 return result;
1368 }
1369
ads1x4s0x_gpio_port_get_raw(const struct device * dev,gpio_port_value_t * value)1370 int ads1x4s0x_gpio_port_get_raw(const struct device *dev, gpio_port_value_t *value)
1371 {
1372 struct ads1x4s0x_data *data = dev->data;
1373 int result = 0;
1374 uint8_t gpio_dat;
1375
1376 k_mutex_lock(&data->gpio_lock, K_FOREVER);
1377
1378 result = ads1x4s0x_read_register(dev, ADS1X4S0X_REGISTER_GPIODAT, &gpio_dat);
1379 data->gpio_value = ADS1X4S0X_REGISTER_GPIODAT_DAT_GET(gpio_dat);
1380 *value = data->gpio_value;
1381
1382 k_mutex_unlock(&data->gpio_lock);
1383
1384 return result;
1385 }
1386
ads1x4s0x_gpio_port_set_masked_raw(const struct device * dev,gpio_port_pins_t mask,gpio_port_value_t value)1387 int ads1x4s0x_gpio_port_set_masked_raw(const struct device *dev, gpio_port_pins_t mask,
1388 gpio_port_value_t value)
1389 {
1390 struct ads1x4s0x_data *data = dev->data;
1391 int result = 0;
1392
1393 k_mutex_lock(&data->gpio_lock, K_FOREVER);
1394
1395 data->gpio_value = ((data->gpio_value & ~mask) | (mask & value)) & data->gpio_enabled &
1396 ~data->gpio_direction;
1397 result = ads1x4s0x_gpio_write_value(dev);
1398
1399 k_mutex_unlock(&data->gpio_lock);
1400
1401 return result;
1402 }
1403
ads1x4s0x_gpio_port_toggle_bits(const struct device * dev,gpio_port_pins_t pins)1404 int ads1x4s0x_gpio_port_toggle_bits(const struct device *dev, gpio_port_pins_t pins)
1405 {
1406 struct ads1x4s0x_data *data = dev->data;
1407 int result = 0;
1408
1409 k_mutex_lock(&data->gpio_lock, K_FOREVER);
1410
1411 data->gpio_value = (data->gpio_value ^ pins) & data->gpio_enabled & ~data->gpio_direction;
1412 result = ads1x4s0x_gpio_write_value(dev);
1413
1414 k_mutex_unlock(&data->gpio_lock);
1415
1416 return result;
1417 }
1418
1419 #endif /* CONFIG_ADC_ADS1X4S0X_GPIO */
1420
ads1x4s0x_init(const struct device * dev)1421 static int ads1x4s0x_init(const struct device *dev)
1422 {
1423 uint8_t status = 0;
1424 uint8_t reference_control = 0;
1425 uint8_t reference_control_read;
1426 int result;
1427 const struct ads1x4s0x_config *config = dev->config;
1428 struct ads1x4s0x_data *data = dev->data;
1429
1430 adc_context_init(&data->ctx);
1431
1432 k_sem_init(&data->data_ready_signal, 0, 1);
1433 k_sem_init(&data->acquire_signal, 0, 1);
1434
1435 #ifdef CONFIG_ADC_ADS1X4S0X_GPIO
1436 k_mutex_init(&data->gpio_lock);
1437 #endif /* CONFIG_ADC_ADS1X4S0X_GPIO */
1438
1439 if (!spi_is_ready_dt(&config->bus)) {
1440 LOG_ERR("%s: SPI device is not ready", dev->name);
1441 return -ENODEV;
1442 }
1443
1444 if (config->gpio_reset.port != NULL) {
1445 result = gpio_pin_configure_dt(&config->gpio_reset, GPIO_OUTPUT_ACTIVE);
1446 if (result != 0) {
1447 LOG_ERR("%s: failed to initialize GPIO for reset", dev->name);
1448 return result;
1449 }
1450 }
1451
1452 if (config->gpio_start_sync.port != NULL) {
1453 result = gpio_pin_configure_dt(&config->gpio_start_sync, GPIO_OUTPUT_INACTIVE);
1454 if (result != 0) {
1455 LOG_ERR("%s: failed to initialize GPIO for start/sync", dev->name);
1456 return result;
1457 }
1458 }
1459
1460 result = gpio_pin_configure_dt(&config->gpio_data_ready, GPIO_INPUT);
1461 if (result != 0) {
1462 LOG_ERR("%s: failed to initialize GPIO for data ready", dev->name);
1463 return result;
1464 }
1465
1466 result = gpio_pin_interrupt_configure_dt(&config->gpio_data_ready, GPIO_INT_EDGE_TO_ACTIVE);
1467 if (result != 0) {
1468 LOG_ERR("%s: failed to configure data ready interrupt", dev->name);
1469 return -EIO;
1470 }
1471
1472 gpio_init_callback(&data->callback_data_ready, ads1x4s0x_data_ready_handler,
1473 BIT(config->gpio_data_ready.pin));
1474 result = gpio_add_callback(config->gpio_data_ready.port, &data->callback_data_ready);
1475 if (result != 0) {
1476 LOG_ERR("%s: failed to add data ready callback", dev->name);
1477 return -EIO;
1478 }
1479
1480 #if CONFIG_ADC_ASYNC
1481 k_tid_t tid = k_thread_create(&data->thread, config->stack,
1482 CONFIG_ADC_ADS1X4S0X_ACQUISITION_THREAD_STACK_SIZE,
1483 ads1x4s0x_acquisition_thread, (void *)dev, NULL, NULL,
1484 CONFIG_ADC_ADS1X4S0X_ASYNC_THREAD_INIT_PRIO, 0, K_NO_WAIT);
1485 k_thread_name_set(tid, "adc_ads1x4s0x");
1486 #endif
1487
1488 k_busy_wait(ADS1X4S0X_POWER_ON_RESET_TIME_IN_US);
1489
1490 if (config->gpio_reset.port == NULL) {
1491 result = ads1x4s0x_send_command(dev, ADS1X4S0X_COMMAND_RESET);
1492 if (result != 0) {
1493 LOG_ERR("%s: unable to send RESET command", dev->name);
1494 return result;
1495 }
1496 } else {
1497 k_busy_wait(ADS1X4S0X_RESET_LOW_TIME_IN_US);
1498 gpio_pin_set_dt(&config->gpio_reset, 0);
1499 }
1500
1501 k_busy_wait(ADS1X4S0X_RESET_DELAY_TIME_IN_US);
1502
1503 result = ads1x4s0x_read_register(dev, ADS1X4S0X_REGISTER_STATUS, &status);
1504 if (result != 0) {
1505 LOG_ERR("%s: unable to read status register", dev->name);
1506 return result;
1507 }
1508
1509 if (ADS1X4S0X_REGISTER_STATUS_NOT_RDY_GET(status) == 0x01) {
1510 LOG_ERR("%s: ADS114 is not yet ready", dev->name);
1511 return -EBUSY;
1512 }
1513
1514 /*
1515 * Activate internal voltage reference during initialization to
1516 * avoid the necessary setup time for it to settle later on.
1517 */
1518 ADS1X4S0X_REGISTER_REF_SET_DEFAULTS(reference_control);
1519
1520 result = ads1x4s0x_write_register(dev, ADS1X4S0X_REGISTER_REF, reference_control);
1521 if (result != 0) {
1522 LOG_ERR("%s: unable to set default reference control values", dev->name);
1523 return result;
1524 }
1525
1526 /*
1527 * Ensure that the internal voltage reference is active.
1528 */
1529 result = ads1x4s0x_read_register(dev, ADS1X4S0X_REGISTER_REF, &reference_control_read);
1530 if (result != 0) {
1531 LOG_ERR("%s: unable to read reference control values", dev->name);
1532 return result;
1533 }
1534
1535 if (reference_control != reference_control_read) {
1536 LOG_ERR("%s: reference control register is incorrect: 0x%02X", dev->name,
1537 reference_control_read);
1538 return -EIO;
1539 }
1540
1541 #ifdef CONFIG_ADC_ADS1X4S0X_GPIO
1542 data->gpio_enabled = 0x00;
1543 data->gpio_direction = 0x0F;
1544 data->gpio_value = 0x00;
1545
1546 result = ads1x4s0x_gpio_write_config(dev);
1547
1548 if (result != 0) {
1549 LOG_ERR("%s: unable to configure defaults for GPIOs", dev->name);
1550 return result;
1551 }
1552 #endif
1553
1554 adc_context_unlock_unconditionally(&data->ctx);
1555
1556 return result;
1557 }
1558
1559 static DEVICE_API(adc, api) = {
1560 .channel_setup = ads1x4s0x_channel_setup,
1561 .read = ads1x4s0x_read,
1562 .ref_internal = ADS1X4S0X_REF_INTERNAL,
1563 #ifdef CONFIG_ADC_ASYNC
1564 .read_async = ads1x4s0x_adc_read_async,
1565 #endif
1566 };
1567 BUILD_ASSERT(CONFIG_ADC_INIT_PRIORITY > CONFIG_SPI_INIT_PRIORITY,
1568 "CONFIG_ADC_INIT_PRIORITY must be higher than CONFIG_SPI_INIT_PRIORITY");
1569
1570 #define ADC_ADS1X4S0X_INST_DEFINE(n, name, ch, res) \
1571 IF_ENABLED( \
1572 CONFIG_ADC_ASYNC, \
1573 (static K_KERNEL_STACK_DEFINE( \
1574 thread_stack_##name##_##n, \
1575 CONFIG_ADC_ADS1X4S0X_ACQUISITION_THREAD_STACK_SIZE);) \
1576 ) \
1577 static const struct ads1x4s0x_config config_##name##_##n = { \
1578 .bus = SPI_DT_SPEC_INST_GET( \
1579 n, SPI_OP_MODE_MASTER | SPI_MODE_CPHA | SPI_WORD_SET(8), 0), \
1580 IF_ENABLED(CONFIG_ADC_ASYNC, (.stack = thread_stack_##name##_##n,)) \
1581 .gpio_reset = GPIO_DT_SPEC_INST_GET_OR(n, reset_gpios, {0}), \
1582 .gpio_data_ready = GPIO_DT_SPEC_INST_GET(n, drdy_gpios), \
1583 .gpio_start_sync = GPIO_DT_SPEC_INST_GET_OR(n, start_sync_gpios, {0}), \
1584 .idac_current = DT_INST_PROP(n, idac_current), \
1585 .vbias_level = DT_INST_PROP(n, vbias_level), \
1586 .vbias_level = DT_INST_PROP(n, vbias_level), \
1587 .resolution = res, \
1588 .channels = ch, \
1589 }; \
1590 static struct ads1x4s0x_data data_##name##_##n; \
1591 DEVICE_DT_INST_DEFINE(n, ads1x4s0x_init, NULL, &data_##name##_##n, &config_##name##_##n, \
1592 POST_KERNEL, CONFIG_ADC_INIT_PRIORITY, &api);
1593
1594 /*
1595 * ADS114S06: 16 bit, 6 channels
1596 */
1597 #define DT_DRV_COMPAT ti_ads114s06
1598 #if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
1599 #define ADC_ADS114S06_INST_DEFINE(n) ADC_ADS1X4S0X_INST_DEFINE(n, ti_ads114s06, 6, 16)
1600 DT_INST_FOREACH_STATUS_OKAY(ADC_ADS114S06_INST_DEFINE);
1601 #endif
1602
1603 /*
1604 * ADS114S08: 16 bit, 12 channels
1605 */
1606 #undef DT_DRV_COMPAT
1607 #define DT_DRV_COMPAT ti_ads114s08
1608 #if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
1609 #define ADC_ADS114S08_INST_DEFINE(n) ADC_ADS1X4S0X_INST_DEFINE(n, ti_ads114s08, 12, 16)
1610 DT_INST_FOREACH_STATUS_OKAY(ADC_ADS114S08_INST_DEFINE);
1611 #endif
1612
1613 /*
1614 * ADS124S06: 24 bit, 6 channels
1615 */
1616 #undef DT_DRV_COMPAT
1617 #define DT_DRV_COMPAT ti_ads124s06
1618 #if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
1619 #define ADC_ADS124S06_INST_DEFINE(n) ADC_ADS1X4S0X_INST_DEFINE(n, ti_ads124s06, 6, 24)
1620 DT_INST_FOREACH_STATUS_OKAY(ADC_ADS124S06_INST_DEFINE);
1621 #endif
1622
1623 /*
1624 * ADS124S08: 24 bit, 12 channels
1625 */
1626 #undef DT_DRV_COMPAT
1627 #define DT_DRV_COMPAT ti_ads124s08
1628 #if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
1629 #define ADC_ADS124S08_INST_DEFINE(n) ADC_ADS1X4S0X_INST_DEFINE(n, ti_ads124s08, 12, 24)
1630 DT_INST_FOREACH_STATUS_OKAY(ADC_ADS124S08_INST_DEFINE);
1631 #endif
1632