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/ads114s0x.h>
10 #include <zephyr/drivers/spi.h>
11 #include <zephyr/drivers/gpio.h>
12 #include <zephyr/dt-bindings/adc/ads114s0x_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 ADC_CONTEXT_USES_KERNEL_TIMER 1
20 #define ADC_CONTEXT_WAIT_FOR_COMPLETION_TIMEOUT \
21 K_MSEC(CONFIG_ADC_ADS114S0X_WAIT_FOR_COMPLETION_TIMEOUT_MS)
22 #include "adc_context.h"
23
24 LOG_MODULE_REGISTER(ads114s0x, CONFIG_ADC_LOG_LEVEL);
25
26 #define ADS114S0X_CLK_FREQ_IN_KHZ 4096
27 #define ADS114S0X_RESET_LOW_TIME_IN_CLOCK_CYCLES 4
28 #define ADS114S0X_START_SYNC_PULSE_DURATION_IN_CLOCK_CYCLES 4
29 #define ADS114S0X_SETUP_TIME_IN_CLOCK_CYCLES 32
30 #define ADS114S0X_INPUT_SELECTION_AINCOM 12
31 #define ADS114S0X_RESOLUTION 16
32 #define ADS114S0X_REF_INTERNAL 2500
33 #define ADS114S0X_GPIO_MAX 3
34 #define ADS114S0X_POWER_ON_RESET_TIME_IN_US 2200
35
36 /* Not mentioned in the datasheet, but instead determined experimentally. */
37 #define ADS114S0X_RESET_DELAY_TIME_SAFETY_MARGIN_IN_US 1000
38 #define ADS114S0X_RESET_DELAY_TIME_IN_US \
39 (4096 * 1000 / ADS114S0X_CLK_FREQ_IN_KHZ + ADS114S0X_RESET_DELAY_TIME_SAFETY_MARGIN_IN_US)
40
41 #define ADS114S0X_RESET_LOW_TIME_IN_US \
42 (ADS114S0X_RESET_LOW_TIME_IN_CLOCK_CYCLES * 1000 / ADS114S0X_CLK_FREQ_IN_KHZ)
43 #define ADS114S0X_START_SYNC_PULSE_DURATION_IN_US \
44 (ADS114S0X_START_SYNC_PULSE_DURATION_IN_CLOCK_CYCLES * 1000 / ADS114S0X_CLK_FREQ_IN_KHZ)
45 #define ADS114S0X_SETUP_TIME_IN_US \
46 (ADS114S0X_SETUP_TIME_IN_CLOCK_CYCLES * 1000 / ADS114S0X_CLK_FREQ_IN_KHZ)
47
48 enum ads114s0x_command {
49 ADS114S0X_COMMAND_NOP = 0x00,
50 ADS114S0X_COMMAND_WAKEUP = 0x02,
51 ADS114S0X_COMMAND_POWERDOWN = 0x04,
52 ADS114S0X_COMMAND_RESET = 0x06,
53 ADS114S0X_COMMAND_START = 0x08,
54 ADS114S0X_COMMAND_STOP = 0x0A,
55 ADS114S0X_COMMAND_SYOCAL = 0x16,
56 ADS114S0X_COMMAND_SYGCAL = 0x17,
57 ADS114S0X_COMMAND_SFOCAL = 0x19,
58 ADS114S0X_COMMAND_RDATA = 0x12,
59 ADS114S0X_COMMAND_RREG = 0x20,
60 ADS114S0X_COMMAND_WREG = 0x40,
61 };
62
63 enum ads114s0x_register {
64 ADS114S0X_REGISTER_ID = 0x00,
65 ADS114S0X_REGISTER_STATUS = 0x01,
66 ADS114S0X_REGISTER_INPMUX = 0x02,
67 ADS114S0X_REGISTER_PGA = 0x03,
68 ADS114S0X_REGISTER_DATARATE = 0x04,
69 ADS114S0X_REGISTER_REF = 0x05,
70 ADS114S0X_REGISTER_IDACMAG = 0x06,
71 ADS114S0X_REGISTER_IDACMUX = 0x07,
72 ADS114S0X_REGISTER_VBIAS = 0x08,
73 ADS114S0X_REGISTER_SYS = 0x09,
74 ADS114S0X_REGISTER_OFCAL0 = 0x0B,
75 ADS114S0X_REGISTER_OFCAL1 = 0x0C,
76 ADS114S0X_REGISTER_FSCAL0 = 0x0E,
77 ADS114S0X_REGISTER_FSCAL1 = 0x0F,
78 ADS114S0X_REGISTER_GPIODAT = 0x10,
79 ADS114S0X_REGISTER_GPIOCON = 0x11,
80 };
81
82 #define ADS114S0X_REGISTER_GET_VALUE(value, pos, length) \
83 FIELD_GET(GENMASK(pos + length - 1, pos), value)
84 #define ADS114S0X_REGISTER_SET_VALUE(target, value, pos, length) \
85 target &= ~GENMASK(pos + length - 1, pos); \
86 target |= FIELD_PREP(GENMASK(pos + length - 1, pos), value)
87
88 #define ADS114S0X_REGISTER_ID_DEV_ID_LENGTH 3
89 #define ADS114S0X_REGISTER_ID_DEV_ID_POS 0
90 #define ADS114S0X_REGISTER_ID_DEV_ID_GET(value) \
91 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_ID_DEV_ID_POS, \
92 ADS114S0X_REGISTER_ID_DEV_ID_LENGTH)
93 #define ADS114S0X_REGISTER_ID_DEV_ID_SET(target, value) \
94 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_ID_DEV_ID_POS, \
95 ADS114S0X_REGISTER_ID_DEV_ID_LENGTH)
96 #define ADS114S0X_REGISTER_STATUS_FL_POR_LENGTH 1
97 #define ADS114S0X_REGISTER_STATUS_FL_POR_POS 7
98 #define ADS114S0X_REGISTER_STATUS_FL_POR_GET(value) \
99 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_STATUS_FL_POR_POS, \
100 ADS114S0X_REGISTER_STATUS_FL_POR_LENGTH)
101 #define ADS114S0X_REGISTER_STATUS_FL_POR_SET(target, value) \
102 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_STATUS_FL_POR_POS, \
103 ADS114S0X_REGISTER_STATUS_FL_POR_LENGTH)
104 #define ADS114S0X_REGISTER_STATUS_NOT_RDY_LENGTH 1
105 #define ADS114S0X_REGISTER_STATUS_NOT_RDY_POS 6
106 #define ADS114S0X_REGISTER_STATUS_NOT_RDY_GET(value) \
107 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_STATUS_NOT_RDY_POS, \
108 ADS114S0X_REGISTER_STATUS_NOT_RDY_LENGTH)
109 #define ADS114S0X_REGISTER_STATUS_NOT_RDY_SET(target, value) \
110 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_STATUS_NOT_RDY_POS, \
111 ADS114S0X_REGISTER_STATUS_NOT_RDY_LENGTH)
112 #define ADS114S0X_REGISTER_STATUS_FL_P_RAILP_LENGTH 1
113 #define ADS114S0X_REGISTER_STATUS_FL_P_RAILP_POS 5
114 #define ADS114S0X_REGISTER_STATUS_FL_P_RAILP_GET(value) \
115 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_STATUS_FL_P_RAILP_POS, \
116 ADS114S0X_REGISTER_STATUS_FL_P_RAILP_LENGTH)
117 #define ADS114S0X_REGISTER_STATUS_FL_P_RAILP_SET(target, value) \
118 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_STATUS_FL_P_RAILP_POS, \
119 ADS114S0X_REGISTER_STATUS_FL_P_RAILP_LENGTH)
120 #define ADS114S0X_REGISTER_STATUS_FL_P_RAILN_LENGTH 1
121 #define ADS114S0X_REGISTER_STATUS_FL_P_RAILN_POS 4
122 #define ADS114S0X_REGISTER_STATUS_FL_P_RAILN_GET(value) \
123 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_STATUS_FL_P_RAILN_POS, \
124 ADS114S0X_REGISTER_STATUS_FL_P_RAILN_LENGTH)
125 #define ADS114S0X_REGISTER_STATUS_FL_P_RAILN_SET(target, value) \
126 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_STATUS_FL_P_RAILN_POS, \
127 ADS114S0X_REGISTER_STATUS_FL_P_RAILN_LENGTH)
128 #define ADS114S0X_REGISTER_STATUS_FL_N_RAILP_LENGTH 1
129 #define ADS114S0X_REGISTER_STATUS_FL_N_RAILP_POS 3
130 #define ADS114S0X_REGISTER_STATUS_FL_N_RAILP_GET(value) \
131 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_STATUS_FL_N_RAILP_POS, \
132 ADS114S0X_REGISTER_STATUS_FL_N_RAILP_LENGTH)
133 #define ADS114S0X_REGISTER_STATUS_FL_N_RAILP_SET(target, value) \
134 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_STATUS_FL_N_RAILP_POS, \
135 ADS114S0X_REGISTER_STATUS_FL_N_RAILP_LENGTH)
136 #define ADS114S0X_REGISTER_STATUS_FL_N_RAILN_LENGTH 1
137 #define ADS114S0X_REGISTER_STATUS_FL_N_RAILN_POS 2
138 #define ADS114S0X_REGISTER_STATUS_FL_N_RAILN_GET(value) \
139 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_STATUS_FL_N_RAILN_POS, \
140 ADS114S0X_REGISTER_STATUS_FL_N_RAILN_LENGTH)
141 #define ADS114S0X_REGISTER_STATUS_FL_N_RAILN_SET(target, value) \
142 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_STATUS_FL_N_RAILN_POS, \
143 ADS114S0X_REGISTER_STATUS_FL_N_RAILN_LENGTH)
144 #define ADS114S0X_REGISTER_STATUS_FL_REF_L1_LENGTH 1
145 #define ADS114S0X_REGISTER_STATUS_FL_REF_L1_POS 1
146 #define ADS114S0X_REGISTER_STATUS_FL_REF_L1_GET(value) \
147 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_STATUS_FL_REF_L1_POS, \
148 ADS114S0X_REGISTER_STATUS_FL_REF_L1_LENGTH)
149 #define ADS114S0X_REGISTER_STATUS_FL_REF_L1_SET(target, value) \
150 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_STATUS_FL_REF_L1_POS, \
151 ADS114S0X_REGISTER_STATUS_FL_REF_L1_LENGTH)
152 #define ADS114S0X_REGISTER_STATUS_FL_REF_L0_LENGTH 1
153 #define ADS114S0X_REGISTER_STATUS_FL_REF_L0_POS 0
154 #define ADS114S0X_REGISTER_STATUS_FL_REF_L0_GET(value) \
155 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_STATUS_FL_REF_L0_POS, \
156 ADS114S0X_REGISTER_STATUS_FL_REF_L0_LENGTH)
157 #define ADS114S0X_REGISTER_STATUS_FL_REF_L0_SET(target, value) \
158 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_STATUS_FL_REF_L0_POS, \
159 ADS114S0X_REGISTER_STATUS_FL_REF_L0_LENGTH)
160 #define ADS114S0X_REGISTER_INPMUX_MUXP_LENGTH 4
161 #define ADS114S0X_REGISTER_INPMUX_MUXP_POS 4
162 #define ADS114S0X_REGISTER_INPMUX_MUXP_GET(value) \
163 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_INPMUX_MUXP_POS, \
164 ADS114S0X_REGISTER_INPMUX_MUXP_LENGTH)
165 #define ADS114S0X_REGISTER_INPMUX_MUXP_SET(target, value) \
166 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_INPMUX_MUXP_POS, \
167 ADS114S0X_REGISTER_INPMUX_MUXP_LENGTH)
168 #define ADS114S0X_REGISTER_INPMUX_MUXN_LENGTH 4
169 #define ADS114S0X_REGISTER_INPMUX_MUXN_POS 0
170 #define ADS114S0X_REGISTER_INPMUX_MUXN_GET(value) \
171 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_INPMUX_MUXN_POS, \
172 ADS114S0X_REGISTER_INPMUX_MUXN_LENGTH)
173 #define ADS114S0X_REGISTER_INPMUX_MUXN_SET(target, value) \
174 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_INPMUX_MUXN_POS, \
175 ADS114S0X_REGISTER_INPMUX_MUXN_LENGTH)
176 #define ADS114S0X_REGISTER_PGA_DELAY_LENGTH 3
177 #define ADS114S0X_REGISTER_PGA_DELAY_POS 5
178 #define ADS114S0X_REGISTER_PGA_DELAY_GET(value) \
179 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_PGA_DELAY_POS, \
180 ADS114S0X_REGISTER_PGA_DELAY_LENGTH)
181 #define ADS114S0X_REGISTER_PGA_DELAY_SET(target, value) \
182 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_PGA_DELAY_POS, \
183 ADS114S0X_REGISTER_PGA_DELAY_LENGTH)
184 #define ADS114S0X_REGISTER_PGA_PGA_EN_LENGTH 2
185 #define ADS114S0X_REGISTER_PGA_PGA_EN_POS 3
186 #define ADS114S0X_REGISTER_PGA_PGA_EN_GET(value) \
187 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_PGA_PGA_EN_POS, \
188 ADS114S0X_REGISTER_PGA_PGA_EN_LENGTH)
189 #define ADS114S0X_REGISTER_PGA_PGA_EN_SET(target, value) \
190 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_PGA_PGA_EN_POS, \
191 ADS114S0X_REGISTER_PGA_PGA_EN_LENGTH)
192 #define ADS114S0X_REGISTER_PGA_GAIN_LENGTH 3
193 #define ADS114S0X_REGISTER_PGA_GAIN_POS 0
194 #define ADS114S0X_REGISTER_PGA_GAIN_GET(value) \
195 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_PGA_GAIN_POS, \
196 ADS114S0X_REGISTER_PGA_GAIN_LENGTH)
197 #define ADS114S0X_REGISTER_PGA_GAIN_SET(target, value) \
198 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_PGA_GAIN_POS, \
199 ADS114S0X_REGISTER_PGA_GAIN_LENGTH)
200 #define ADS114S0X_REGISTER_DATARATE_G_CHOP_LENGTH 1
201 #define ADS114S0X_REGISTER_DATARATE_G_CHOP_POS 7
202 #define ADS114S0X_REGISTER_DATARATE_G_CHOP_GET(value) \
203 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_DATARATE_G_CHOP_POS, \
204 ADS114S0X_REGISTER_DATARATE_G_CHOP_LENGTH)
205 #define ADS114S0X_REGISTER_DATARATE_G_CHOP_SET(target, value) \
206 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_DATARATE_G_CHOP_POS, \
207 ADS114S0X_REGISTER_DATARATE_G_CHOP_LENGTH)
208 #define ADS114S0X_REGISTER_DATARATE_CLK_LENGTH 1
209 #define ADS114S0X_REGISTER_DATARATE_CLK_POS 6
210 #define ADS114S0X_REGISTER_DATARATE_CLK_GET(value) \
211 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_DATARATE_CLK_POS, \
212 ADS114S0X_REGISTER_DATARATE_CLK_LENGTH)
213 #define ADS114S0X_REGISTER_DATARATE_CLK_SET(target, value) \
214 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_DATARATE_CLK_POS, \
215 ADS114S0X_REGISTER_DATARATE_CLK_LENGTH)
216 #define ADS114S0X_REGISTER_DATARATE_MODE_LENGTH 1
217 #define ADS114S0X_REGISTER_DATARATE_MODE_POS 5
218 #define ADS114S0X_REGISTER_DATARATE_MODE_GET(value) \
219 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_DATARATE_MODE_POS, \
220 ADS114S0X_REGISTER_DATARATE_MODE_LENGTH)
221 #define ADS114S0X_REGISTER_DATARATE_MODE_SET(target, value) \
222 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_DATARATE_MODE_POS, \
223 ADS114S0X_REGISTER_DATARATE_MODE_LENGTH)
224 #define ADS114S0X_REGISTER_DATARATE_FILTER_LENGTH 1
225 #define ADS114S0X_REGISTER_DATARATE_FILTER_POS 4
226 #define ADS114S0X_REGISTER_DATARATE_FILTER_GET(value) \
227 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_DATARATE_FILTER_POS, \
228 ADS114S0X_REGISTER_DATARATE_FILTER_LENGTH)
229 #define ADS114S0X_REGISTER_DATARATE_FILTER_SET(target, value) \
230 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_DATARATE_FILTER_POS, \
231 ADS114S0X_REGISTER_DATARATE_FILTER_LENGTH)
232 #define ADS114S0X_REGISTER_DATARATE_DR_LENGTH 4
233 #define ADS114S0X_REGISTER_DATARATE_DR_POS 0
234 #define ADS114S0X_REGISTER_DATARATE_DR_GET(value) \
235 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_DATARATE_DR_POS, \
236 ADS114S0X_REGISTER_DATARATE_DR_LENGTH)
237 #define ADS114S0X_REGISTER_DATARATE_DR_SET(target, value) \
238 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_DATARATE_DR_POS, \
239 ADS114S0X_REGISTER_DATARATE_DR_LENGTH)
240 #define ADS114S0X_REGISTER_REF_FL_REF_EN_LENGTH 2
241 #define ADS114S0X_REGISTER_REF_FL_REF_EN_POS 6
242 #define ADS114S0X_REGISTER_REF_FL_REF_EN_GET(value) \
243 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_REF_FL_REF_EN_POS, \
244 ADS114S0X_REGISTER_REF_FL_REF_EN_LENGTH)
245 #define ADS114S0X_REGISTER_REF_FL_REF_EN_SET(target, value) \
246 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_REF_FL_REF_EN_POS, \
247 ADS114S0X_REGISTER_REF_FL_REF_EN_LENGTH)
248 #define ADS114S0X_REGISTER_REF_NOT_REFP_BUF_LENGTH 1
249 #define ADS114S0X_REGISTER_REF_NOT_REFP_BUF_POS 5
250 #define ADS114S0X_REGISTER_REF_NOT_REFP_BUF_GET(value) \
251 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_REF_NOT_REFP_BUF_POS, \
252 ADS114S0X_REGISTER_REF_NOT_REFP_BUF_LENGTH)
253 #define ADS114S0X_REGISTER_REF_NOT_REFP_BUF_SET(target, value) \
254 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_REF_NOT_REFP_BUF_POS, \
255 ADS114S0X_REGISTER_REF_NOT_REFP_BUF_LENGTH)
256 #define ADS114S0X_REGISTER_REF_NOT_REFN_BUF_LENGTH 1
257 #define ADS114S0X_REGISTER_REF_NOT_REFN_BUF_POS 4
258 #define ADS114S0X_REGISTER_REF_NOT_REFN_BUF_GET(value) \
259 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_REF_NOT_REFN_BUF_POS, \
260 ADS114S0X_REGISTER_REF_NOT_REFN_BUF_LENGTH)
261 #define ADS114S0X_REGISTER_REF_NOT_REFN_BUF_SET(target, value) \
262 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_REF_NOT_REFN_BUF_POS, \
263 ADS114S0X_REGISTER_REF_NOT_REFN_BUF_LENGTH)
264 #define ADS114S0X_REGISTER_REF_REFSEL_LENGTH 2
265 #define ADS114S0X_REGISTER_REF_REFSEL_POS 2
266 #define ADS114S0X_REGISTER_REF_REFSEL_GET(value) \
267 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_REF_REFSEL_POS, \
268 ADS114S0X_REGISTER_REF_REFSEL_LENGTH)
269 #define ADS114S0X_REGISTER_REF_REFSEL_SET(target, value) \
270 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_REF_REFSEL_POS, \
271 ADS114S0X_REGISTER_REF_REFSEL_LENGTH)
272 #define ADS114S0X_REGISTER_REF_REFCON_LENGTH 2
273 #define ADS114S0X_REGISTER_REF_REFCON_POS 0
274 #define ADS114S0X_REGISTER_REF_REFCON_GET(value) \
275 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_REF_REFCON_POS, \
276 ADS114S0X_REGISTER_REF_REFCON_LENGTH)
277 #define ADS114S0X_REGISTER_REF_REFCON_SET(target, value) \
278 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_REF_REFCON_POS, \
279 ADS114S0X_REGISTER_REF_REFCON_LENGTH)
280 #define ADS114S0X_REGISTER_IDACMAG_FL_RAIL_EN_LENGTH 1
281 #define ADS114S0X_REGISTER_IDACMAG_FL_RAIL_EN_POS 7
282 #define ADS114S0X_REGISTER_IDACMAG_FL_RAIL_EN_GET(value) \
283 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_IDACMAG_FL_RAIL_EN_POS, \
284 ADS114S0X_REGISTER_IDACMAG_FL_RAIL_EN_LENGTH)
285 #define ADS114S0X_REGISTER_IDACMAG_FL_RAIL_EN_SET(target, value) \
286 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_IDACMAG_FL_RAIL_EN_POS, \
287 ADS114S0X_REGISTER_IDACMAG_FL_RAIL_EN_LENGTH)
288 #define ADS114S0X_REGISTER_IDACMAG_PSW_LENGTH 1
289 #define ADS114S0X_REGISTER_IDACMAG_PSW_POS 6
290 #define ADS114S0X_REGISTER_IDACMAG_PSW_GET(value) \
291 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_IDACMAG_PSW_POS, \
292 ADS114S0X_REGISTER_IDACMAG_PSW_LENGTH)
293 #define ADS114S0X_REGISTER_IDACMAG_PSW_SET(target, value) \
294 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_IDACMAG_PSW_POS, \
295 ADS114S0X_REGISTER_IDACMAG_PSW_LENGTH)
296 #define ADS114S0X_REGISTER_IDACMAG_IMAG_LENGTH 4
297 #define ADS114S0X_REGISTER_IDACMAG_IMAG_POS 0
298 #define ADS114S0X_REGISTER_IDACMAG_IMAG_GET(value) \
299 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_IDACMAG_IMAG_POS, \
300 ADS114S0X_REGISTER_IDACMAG_IMAG_LENGTH)
301 #define ADS114S0X_REGISTER_IDACMAG_IMAG_SET(target, value) \
302 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_IDACMAG_IMAG_POS, \
303 ADS114S0X_REGISTER_IDACMAG_IMAG_LENGTH)
304 #define ADS114S0X_REGISTER_IDACMUX_I2MUX_LENGTH 4
305 #define ADS114S0X_REGISTER_IDACMUX_I2MUX_POS 4
306 #define ADS114S0X_REGISTER_IDACMUX_I2MUX_GET(value) \
307 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_IDACMUX_I2MUX_POS, \
308 ADS114S0X_REGISTER_IDACMUX_I2MUX_LENGTH)
309 #define ADS114S0X_REGISTER_IDACMUX_I2MUX_SET(target, value) \
310 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_IDACMUX_I2MUX_POS, \
311 ADS114S0X_REGISTER_IDACMUX_I2MUX_LENGTH)
312 #define ADS114S0X_REGISTER_IDACMUX_I1MUX_LENGTH 4
313 #define ADS114S0X_REGISTER_IDACMUX_I1MUX_POS 0
314 #define ADS114S0X_REGISTER_IDACMUX_I1MUX_GET(value) \
315 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_IDACMUX_I1MUX_POS, \
316 ADS114S0X_REGISTER_IDACMUX_I1MUX_LENGTH)
317 #define ADS114S0X_REGISTER_IDACMUX_I1MUX_SET(target, value) \
318 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_IDACMUX_I1MUX_POS, \
319 ADS114S0X_REGISTER_IDACMUX_I1MUX_LENGTH)
320 #define ADS114S0X_REGISTER_GPIODAT_DIR_LENGTH 4
321 #define ADS114S0X_REGISTER_GPIODAT_DIR_POS 4
322 #define ADS114S0X_REGISTER_GPIODAT_DIR_GET(value) \
323 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_GPIODAT_DIR_POS, \
324 ADS114S0X_REGISTER_GPIODAT_DIR_LENGTH)
325 #define ADS114S0X_REGISTER_GPIODAT_DIR_SET(target, value) \
326 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_GPIODAT_DIR_POS, \
327 ADS114S0X_REGISTER_GPIODAT_DIR_LENGTH)
328 #define ADS114S0X_REGISTER_GPIODAT_DAT_LENGTH 4
329 #define ADS114S0X_REGISTER_GPIODAT_DAT_POS 0
330 #define ADS114S0X_REGISTER_GPIODAT_DAT_GET(value) \
331 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_GPIODAT_DAT_POS, \
332 ADS114S0X_REGISTER_GPIODAT_DAT_LENGTH)
333 #define ADS114S0X_REGISTER_GPIODAT_DAT_SET(target, value) \
334 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_GPIODAT_DAT_POS, \
335 ADS114S0X_REGISTER_GPIODAT_DAT_LENGTH)
336 #define ADS114S0X_REGISTER_GPIOCON_CON_LENGTH 4
337 #define ADS114S0X_REGISTER_GPIOCON_CON_POS 0
338 #define ADS114S0X_REGISTER_GPIOCON_CON_GET(value) \
339 ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_GPIOCON_CON_POS, \
340 ADS114S0X_REGISTER_GPIOCON_CON_LENGTH)
341 #define ADS114S0X_REGISTER_GPIOCON_CON_SET(target, value) \
342 ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_GPIOCON_CON_POS, \
343 ADS114S0X_REGISTER_GPIOCON_CON_LENGTH)
344
345 /*
346 * - AIN0 as positive input
347 * - AIN1 as negative input
348 */
349 #define ADS114S0X_REGISTER_INPMUX_SET_DEFAULTS(target) \
350 ADS114S0X_REGISTER_INPMUX_MUXP_SET(target, 0b0000); \
351 ADS114S0X_REGISTER_INPMUX_MUXN_SET(target, 0b0001)
352 /*
353 * - disable reference monitor
354 * - enable positive reference buffer
355 * - disable negative reference buffer
356 * - use internal reference
357 * - enable internal voltage reference
358 */
359 #define ADS114S0X_REGISTER_REF_SET_DEFAULTS(target) \
360 ADS114S0X_REGISTER_REF_FL_REF_EN_SET(target, 0b00); \
361 ADS114S0X_REGISTER_REF_NOT_REFP_BUF_SET(target, 0b0); \
362 ADS114S0X_REGISTER_REF_NOT_REFN_BUF_SET(target, 0b1); \
363 ADS114S0X_REGISTER_REF_REFSEL_SET(target, 0b10); \
364 ADS114S0X_REGISTER_REF_REFCON_SET(target, 0b01)
365 /*
366 * - disable global chop
367 * - use internal oscillator
368 * - single shot conversion mode
369 * - low latency filter
370 * - 20 samples per second
371 */
372 #define ADS114S0X_REGISTER_DATARATE_SET_DEFAULTS(target) \
373 ADS114S0X_REGISTER_DATARATE_G_CHOP_SET(target, 0b0); \
374 ADS114S0X_REGISTER_DATARATE_CLK_SET(target, 0b0); \
375 ADS114S0X_REGISTER_DATARATE_MODE_SET(target, 0b1); \
376 ADS114S0X_REGISTER_DATARATE_FILTER_SET(target, 0b1); \
377 ADS114S0X_REGISTER_DATARATE_DR_SET(target, 0b0100)
378 /*
379 * - delay of 14*t_mod
380 * - disable gain
381 * - gain 1
382 */
383 #define ADS114S0X_REGISTER_PGA_SET_DEFAULTS(target) \
384 ADS114S0X_REGISTER_PGA_DELAY_SET(target, 0b000); \
385 ADS114S0X_REGISTER_PGA_PGA_EN_SET(target, 0b00); \
386 ADS114S0X_REGISTER_PGA_GAIN_SET(target, 0b000)
387 /*
388 * - disable PGA output rail flag
389 * - low-side power switch
390 * - IDAC off
391 */
392 #define ADS114S0X_REGISTER_IDACMAG_SET_DEFAULTS(target) \
393 ADS114S0X_REGISTER_IDACMAG_FL_RAIL_EN_SET(target, 0b0); \
394 ADS114S0X_REGISTER_IDACMAG_PSW_SET(target, 0b0); \
395 ADS114S0X_REGISTER_IDACMAG_IMAG_SET(target, 0b0000)
396 /*
397 * - disconnect IDAC1
398 * - disconnect IDAC2
399 */
400 #define ADS114S0X_REGISTER_IDACMUX_SET_DEFAULTS(target) \
401 ADS114S0X_REGISTER_IDACMUX_I1MUX_SET(target, 0b1111); \
402 ADS114S0X_REGISTER_IDACMUX_I2MUX_SET(target, 0b1111)
403
404 struct ads114s0x_config {
405 struct spi_dt_spec bus;
406 #if CONFIG_ADC_ASYNC
407 k_thread_stack_t *stack;
408 #endif
409 const struct gpio_dt_spec gpio_reset;
410 const struct gpio_dt_spec gpio_data_ready;
411 const struct gpio_dt_spec gpio_start_sync;
412 int idac_current;
413 };
414
415 struct ads114s0x_data {
416 struct adc_context ctx;
417 #if CONFIG_ADC_ASYNC
418 struct k_thread thread;
419 #endif /* CONFIG_ADC_ASYNC */
420 struct gpio_callback callback_data_ready;
421 struct k_sem data_ready_signal;
422 struct k_sem acquire_signal;
423 int16_t *buffer;
424 int16_t *buffer_ptr;
425 #if CONFIG_ADC_ADS114S0X_GPIO
426 struct k_mutex gpio_lock;
427 uint8_t gpio_enabled; /* one bit per GPIO, 1 = enabled */
428 uint8_t gpio_direction; /* one bit per GPIO, 1 = input */
429 uint8_t gpio_value; /* one bit per GPIO, 1 = high */
430 #endif /* CONFIG_ADC_ADS114S0X_GPIO */
431 };
432
ads114s0x_data_ready_handler(const struct device * dev,struct gpio_callback * gpio_cb,uint32_t pins)433 static void ads114s0x_data_ready_handler(const struct device *dev, struct gpio_callback *gpio_cb,
434 uint32_t pins)
435 {
436 ARG_UNUSED(dev);
437 ARG_UNUSED(pins);
438
439 struct ads114s0x_data *data =
440 CONTAINER_OF(gpio_cb, struct ads114s0x_data, callback_data_ready);
441
442 k_sem_give(&data->data_ready_signal);
443 }
444
ads114s0x_read_register(const struct spi_dt_spec * bus,enum ads114s0x_register register_address,uint8_t * value)445 static int ads114s0x_read_register(const struct spi_dt_spec *bus,
446 enum ads114s0x_register register_address, uint8_t *value)
447 {
448 uint8_t buffer_tx[3];
449 uint8_t buffer_rx[ARRAY_SIZE(buffer_tx)];
450 const struct spi_buf tx_buf[] = {{
451 .buf = buffer_tx,
452 .len = ARRAY_SIZE(buffer_tx),
453 }};
454 const struct spi_buf rx_buf[] = {{
455 .buf = buffer_rx,
456 .len = ARRAY_SIZE(buffer_rx),
457 }};
458 const struct spi_buf_set tx = {
459 .buffers = tx_buf,
460 .count = ARRAY_SIZE(tx_buf),
461 };
462 const struct spi_buf_set rx = {
463 .buffers = rx_buf,
464 .count = ARRAY_SIZE(rx_buf),
465 };
466
467 buffer_tx[0] = ((uint8_t)ADS114S0X_COMMAND_RREG) | ((uint8_t)register_address);
468 /* read one register */
469 buffer_tx[1] = 0x00;
470
471 int result = spi_transceive_dt(bus, &tx, &rx);
472
473 if (result != 0) {
474 LOG_ERR("spi_transceive failed with error %i", result);
475 return result;
476 }
477
478 *value = buffer_rx[2];
479 LOG_DBG("read from register 0x%02X value 0x%02X", register_address, *value);
480
481 return 0;
482 }
483
ads114s0x_write_register(const struct spi_dt_spec * bus,enum ads114s0x_register register_address,uint8_t value)484 static int ads114s0x_write_register(const struct spi_dt_spec *bus,
485 enum ads114s0x_register register_address, uint8_t value)
486 {
487 uint8_t buffer_tx[3];
488 const struct spi_buf tx_buf[] = {{
489 .buf = buffer_tx,
490 .len = ARRAY_SIZE(buffer_tx),
491 }};
492 const struct spi_buf_set tx = {
493 .buffers = tx_buf,
494 .count = ARRAY_SIZE(tx_buf),
495 };
496
497 buffer_tx[0] = ((uint8_t)ADS114S0X_COMMAND_WREG) | ((uint8_t)register_address);
498 /* write one register */
499 buffer_tx[1] = 0x00;
500 buffer_tx[2] = value;
501
502 LOG_DBG("writing to register 0x%02X value 0x%02X", register_address, value);
503 int result = spi_write_dt(bus, &tx);
504
505 if (result != 0) {
506 LOG_ERR("spi_write failed with error %i", result);
507 return result;
508 }
509
510 return 0;
511 }
512
ads114s0x_write_multiple_registers(const struct spi_dt_spec * bus,enum ads114s0x_register * register_addresses,uint8_t * values,size_t count)513 static int ads114s0x_write_multiple_registers(const struct spi_dt_spec *bus,
514 enum ads114s0x_register *register_addresses,
515 uint8_t *values, size_t count)
516 {
517 uint8_t buffer_tx[2];
518 const struct spi_buf tx_buf[] = {
519 {
520 .buf = buffer_tx,
521 .len = ARRAY_SIZE(buffer_tx),
522 },
523 {
524 .buf = values,
525 .len = count,
526 },
527 };
528 const struct spi_buf_set tx = {
529 .buffers = tx_buf,
530 .count = ARRAY_SIZE(tx_buf),
531 };
532
533 if (count == 0) {
534 LOG_WRN("ignoring the command to write 0 registers");
535 return -EINVAL;
536 }
537
538 buffer_tx[0] = ((uint8_t)ADS114S0X_COMMAND_WREG) | ((uint8_t)register_addresses[0]);
539 buffer_tx[1] = count - 1;
540
541 LOG_HEXDUMP_DBG(register_addresses, count, "writing to registers");
542 LOG_HEXDUMP_DBG(values, count, "values");
543
544 /* ensure that the register addresses are in the correct order */
545 for (size_t i = 1; i < count; ++i) {
546 __ASSERT(register_addresses[i - 1] + 1 == register_addresses[i],
547 "register addresses are not consecutive");
548 }
549
550 int result = spi_write_dt(bus, &tx);
551
552 if (result != 0) {
553 LOG_ERR("spi_write failed with error %i", result);
554 return result;
555 }
556
557 return 0;
558 }
559
ads114s0x_send_command(const struct spi_dt_spec * bus,enum ads114s0x_command command)560 static int ads114s0x_send_command(const struct spi_dt_spec *bus, enum ads114s0x_command command)
561 {
562 uint8_t buffer_tx[1];
563 const struct spi_buf tx_buf[] = {{
564 .buf = buffer_tx,
565 .len = ARRAY_SIZE(buffer_tx),
566 }};
567 const struct spi_buf_set tx = {
568 .buffers = tx_buf,
569 .count = ARRAY_SIZE(tx_buf),
570 };
571
572 buffer_tx[0] = (uint8_t)command;
573
574 LOG_DBG("sending command 0x%02X", command);
575 int result = spi_write_dt(bus, &tx);
576
577 if (result != 0) {
578 LOG_ERR("spi_write failed with error %i", result);
579 return result;
580 }
581
582 return 0;
583 }
584
ads114s0x_channel_setup(const struct device * dev,const struct adc_channel_cfg * channel_cfg)585 static int ads114s0x_channel_setup(const struct device *dev,
586 const struct adc_channel_cfg *channel_cfg)
587 {
588 const struct ads114s0x_config *config = dev->config;
589 uint8_t input_mux = 0;
590 uint8_t reference_control = 0;
591 uint8_t data_rate = 0;
592 uint8_t gain = 0;
593 uint8_t idac_magnitude = 0;
594 uint8_t idac_mux = 0;
595 uint8_t pin_selections[4];
596 size_t pin_selections_size;
597 int result;
598 enum ads114s0x_register register_addresses[6];
599 uint8_t values[ARRAY_SIZE(register_addresses)];
600 uint16_t acquisition_time_value = ADC_ACQ_TIME_VALUE(channel_cfg->acquisition_time);
601 uint16_t acquisition_time_unit = ADC_ACQ_TIME_UNIT(channel_cfg->acquisition_time);
602
603 ADS114S0X_REGISTER_INPMUX_SET_DEFAULTS(gain);
604 ADS114S0X_REGISTER_REF_SET_DEFAULTS(reference_control);
605 ADS114S0X_REGISTER_DATARATE_SET_DEFAULTS(data_rate);
606 ADS114S0X_REGISTER_PGA_SET_DEFAULTS(gain);
607 ADS114S0X_REGISTER_IDACMAG_SET_DEFAULTS(idac_magnitude);
608 ADS114S0X_REGISTER_IDACMUX_SET_DEFAULTS(idac_mux);
609
610 if (channel_cfg->channel_id != 0) {
611 LOG_ERR("only one channel is supported");
612 return -EINVAL;
613 }
614
615 /* The ADS114 uses samples per seconds units with the lowest being 2.5SPS
616 * and with acquisition_time only having 14b for time, this will not fit
617 * within here for microsecond units. Use Tick units and allow the user to
618 * specify the ODR directly.
619 */
620 if (channel_cfg->acquisition_time != ADC_ACQ_TIME_DEFAULT &&
621 acquisition_time_unit != ADC_ACQ_TIME_TICKS) {
622 LOG_ERR("invalid acquisition time %i", channel_cfg->acquisition_time);
623 return -EINVAL;
624 }
625
626 if (channel_cfg->acquisition_time == ADC_ACQ_TIME_DEFAULT) {
627 ADS114S0X_REGISTER_DATARATE_DR_SET(data_rate, ADS114S0X_CONFIG_DR_20);
628 } else {
629 ADS114S0X_REGISTER_DATARATE_DR_SET(data_rate, acquisition_time_value);
630 }
631
632 switch (channel_cfg->reference) {
633 case ADC_REF_INTERNAL:
634 /* disable negative reference buffer */
635 ADS114S0X_REGISTER_REF_NOT_REFN_BUF_SET(reference_control, 0b1);
636 /* disable positive reference buffer */
637 ADS114S0X_REGISTER_REF_NOT_REFP_BUF_SET(reference_control, 0b1);
638 /* use internal reference */
639 ADS114S0X_REGISTER_REF_REFSEL_SET(reference_control, 0b10);
640 break;
641 case ADC_REF_EXTERNAL0:
642 /* enable negative reference buffer */
643 ADS114S0X_REGISTER_REF_NOT_REFN_BUF_SET(reference_control, 0b0);
644 /* enable positive reference buffer */
645 ADS114S0X_REGISTER_REF_NOT_REFP_BUF_SET(reference_control, 0b0);
646 /* use external reference 0*/
647 ADS114S0X_REGISTER_REF_REFSEL_SET(reference_control, 0b00);
648 break;
649 case ADC_REF_EXTERNAL1:
650 /* enable negative reference buffer */
651 ADS114S0X_REGISTER_REF_NOT_REFN_BUF_SET(reference_control, 0b0);
652 /* enable positive reference buffer */
653 ADS114S0X_REGISTER_REF_NOT_REFP_BUF_SET(reference_control, 0b0);
654 /* use external reference 0*/
655 ADS114S0X_REGISTER_REF_REFSEL_SET(reference_control, 0b01);
656 break;
657 default:
658 LOG_ERR("reference %i is not supported", channel_cfg->reference);
659 return -EINVAL;
660 }
661
662 if (channel_cfg->differential) {
663 if (channel_cfg->input_positive >= ADS114S0X_INPUT_SELECTION_AINCOM) {
664 LOG_ERR("positive channel input %i is invalid",
665 channel_cfg->input_positive);
666 return -EINVAL;
667 }
668
669 if (channel_cfg->input_negative >= ADS114S0X_INPUT_SELECTION_AINCOM) {
670 LOG_ERR("negative channel input %i is invalid",
671 channel_cfg->input_negative);
672 return -EINVAL;
673 }
674
675 if (channel_cfg->input_positive == channel_cfg->input_negative) {
676 LOG_ERR("negative and positive channel inputs must be different");
677 return -EINVAL;
678 }
679
680 ADS114S0X_REGISTER_INPMUX_MUXP_SET(input_mux, channel_cfg->input_positive);
681 ADS114S0X_REGISTER_INPMUX_MUXN_SET(input_mux, channel_cfg->input_negative);
682 pin_selections[0] = channel_cfg->input_positive;
683 pin_selections[1] = channel_cfg->input_negative;
684 } else {
685 if (channel_cfg->input_positive >= ADS114S0X_INPUT_SELECTION_AINCOM) {
686 LOG_ERR("channel input %i is invalid", channel_cfg->input_positive);
687 return -EINVAL;
688 }
689
690 ADS114S0X_REGISTER_INPMUX_MUXP_SET(input_mux, channel_cfg->input_positive);
691 ADS114S0X_REGISTER_INPMUX_MUXN_SET(input_mux, ADS114S0X_INPUT_SELECTION_AINCOM);
692 pin_selections[0] = channel_cfg->input_positive;
693 pin_selections[1] = ADS114S0X_INPUT_SELECTION_AINCOM;
694 }
695
696 switch (channel_cfg->gain) {
697 case ADC_GAIN_1:
698 /* set gain value */
699 ADS114S0X_REGISTER_PGA_GAIN_SET(gain, 0b000);
700 break;
701 case ADC_GAIN_2:
702 ADS114S0X_REGISTER_PGA_GAIN_SET(gain, 0b001);
703 break;
704 case ADC_GAIN_4:
705 ADS114S0X_REGISTER_PGA_GAIN_SET(gain, 0b010);
706 break;
707 case ADC_GAIN_8:
708 ADS114S0X_REGISTER_PGA_GAIN_SET(gain, 0b011);
709 break;
710 case ADC_GAIN_16:
711 ADS114S0X_REGISTER_PGA_GAIN_SET(gain, 0b100);
712 break;
713 case ADC_GAIN_32:
714 ADS114S0X_REGISTER_PGA_GAIN_SET(gain, 0b101);
715 break;
716 case ADC_GAIN_64:
717 ADS114S0X_REGISTER_PGA_GAIN_SET(gain, 0b110);
718 break;
719 case ADC_GAIN_128:
720 ADS114S0X_REGISTER_PGA_GAIN_SET(gain, 0b111);
721 break;
722 default:
723 LOG_ERR("gain value %i not supported", channel_cfg->gain);
724 return -EINVAL;
725 }
726
727 if (channel_cfg->gain != ADC_GAIN_1) {
728 /* enable gain */
729 ADS114S0X_REGISTER_PGA_PGA_EN_SET(gain, 0b01);
730 }
731
732 switch (config->idac_current) {
733 case 0:
734 ADS114S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0000);
735 break;
736 case 10:
737 ADS114S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0001);
738 break;
739 case 50:
740 ADS114S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0010);
741 break;
742 case 100:
743 ADS114S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0011);
744 break;
745 case 250:
746 ADS114S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0100);
747 break;
748 case 500:
749 ADS114S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0101);
750 break;
751 case 750:
752 ADS114S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0110);
753 break;
754 case 1000:
755 ADS114S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0111);
756 break;
757 case 1500:
758 ADS114S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b1000);
759 break;
760 case 2000:
761 ADS114S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b1001);
762 break;
763 default:
764 LOG_ERR("IDAC magnitude %i not supported", config->idac_current);
765 return -EINVAL;
766 }
767
768 if (channel_cfg->current_source_pin_set) {
769 if (channel_cfg->current_source_pin[0] > 0b1111) {
770 LOG_ERR("invalid selection %i for I1MUX",
771 channel_cfg->current_source_pin[0]);
772 return -EINVAL;
773 }
774
775 if (channel_cfg->current_source_pin[1] > 0b1111) {
776 LOG_ERR("invalid selection %i for I2MUX",
777 channel_cfg->current_source_pin[1]);
778 return -EINVAL;
779 }
780
781 ADS114S0X_REGISTER_IDACMUX_I1MUX_SET(idac_mux, channel_cfg->current_source_pin[0]);
782 ADS114S0X_REGISTER_IDACMUX_I2MUX_SET(idac_mux, channel_cfg->current_source_pin[1]);
783 pin_selections[2] = channel_cfg->current_source_pin[0];
784 pin_selections[3] = channel_cfg->current_source_pin[1];
785 pin_selections_size = 4;
786 } else {
787 pin_selections_size = 2;
788 }
789
790 for (size_t i = 0; i < pin_selections_size; ++i) {
791 if (pin_selections[i] > ADS114S0X_INPUT_SELECTION_AINCOM) {
792 continue;
793 }
794
795 for (size_t j = i + 1; j < pin_selections_size; ++j) {
796 if (pin_selections[j] > ADS114S0X_INPUT_SELECTION_AINCOM) {
797 continue;
798 }
799
800 if (pin_selections[i] == pin_selections[j]) {
801 LOG_ERR("pins for inputs and current sources must be different");
802 return -EINVAL;
803 }
804 }
805 }
806
807 register_addresses[0] = ADS114S0X_REGISTER_INPMUX;
808 register_addresses[1] = ADS114S0X_REGISTER_PGA;
809 register_addresses[2] = ADS114S0X_REGISTER_DATARATE;
810 register_addresses[3] = ADS114S0X_REGISTER_REF;
811 register_addresses[4] = ADS114S0X_REGISTER_IDACMAG;
812 register_addresses[5] = ADS114S0X_REGISTER_IDACMUX;
813 BUILD_ASSERT(ARRAY_SIZE(register_addresses) == 6);
814 values[0] = input_mux;
815 values[1] = gain;
816 values[2] = data_rate;
817 values[3] = reference_control;
818 values[4] = idac_magnitude;
819 values[5] = idac_mux;
820 BUILD_ASSERT(ARRAY_SIZE(values) == 6);
821
822 result = ads114s0x_write_multiple_registers(&config->bus, register_addresses, values,
823 ARRAY_SIZE(values));
824
825 if (result != 0) {
826 LOG_ERR("unable to configure registers");
827 return result;
828 }
829
830 return 0;
831 }
832
ads114s0x_validate_buffer_size(const struct adc_sequence * sequence)833 static int ads114s0x_validate_buffer_size(const struct adc_sequence *sequence)
834 {
835 size_t needed = sizeof(int16_t);
836
837 if (sequence->options) {
838 needed *= (1 + sequence->options->extra_samplings);
839 }
840
841 if (sequence->buffer_size < needed) {
842 return -ENOMEM;
843 }
844
845 return 0;
846 }
847
ads114s0x_validate_sequence(const struct device * dev,const struct adc_sequence * sequence)848 static int ads114s0x_validate_sequence(const struct device *dev,
849 const struct adc_sequence *sequence)
850 {
851 if (sequence->resolution != ADS114S0X_RESOLUTION) {
852 LOG_ERR("invalid resolution");
853 return -EINVAL;
854 }
855
856 if (sequence->channels != BIT(0)) {
857 LOG_ERR("invalid channel");
858 return -EINVAL;
859 }
860
861 if (sequence->oversampling) {
862 LOG_ERR("oversampling is not supported");
863 return -EINVAL;
864 }
865
866 return ads114s0x_validate_buffer_size(sequence);
867 }
868
adc_context_update_buffer_pointer(struct adc_context * ctx,bool repeat_sampling)869 static void adc_context_update_buffer_pointer(struct adc_context *ctx, bool repeat_sampling)
870 {
871 struct ads114s0x_data *data = CONTAINER_OF(ctx, struct ads114s0x_data, ctx);
872
873 if (repeat_sampling) {
874 data->buffer = data->buffer_ptr;
875 }
876 }
877
adc_context_start_sampling(struct adc_context * ctx)878 static void adc_context_start_sampling(struct adc_context *ctx)
879 {
880 struct ads114s0x_data *data = CONTAINER_OF(ctx, struct ads114s0x_data, ctx);
881
882 data->buffer_ptr = data->buffer;
883 k_sem_give(&data->acquire_signal);
884 }
885
ads114s0x_adc_start_read(const struct device * dev,const struct adc_sequence * sequence,bool wait)886 static int ads114s0x_adc_start_read(const struct device *dev, const struct adc_sequence *sequence,
887 bool wait)
888 {
889 int result;
890 struct ads114s0x_data *data = dev->data;
891
892 result = ads114s0x_validate_sequence(dev, sequence);
893
894 if (result != 0) {
895 LOG_ERR("sequence validation failed");
896 return result;
897 }
898
899 data->buffer = sequence->buffer;
900
901 adc_context_start_read(&data->ctx, sequence);
902
903 if (wait) {
904 result = adc_context_wait_for_completion(&data->ctx);
905 }
906
907 return result;
908 }
909
ads114s0x_send_start_read(const struct device * dev)910 static int ads114s0x_send_start_read(const struct device *dev)
911 {
912 const struct ads114s0x_config *config = dev->config;
913 int result;
914
915 if (config->gpio_start_sync.port == 0) {
916 result = ads114s0x_send_command(&config->bus, ADS114S0X_COMMAND_START);
917 if (result != 0) {
918 LOG_ERR("unable to send START/SYNC command");
919 return result;
920 }
921 } else {
922 result = gpio_pin_set_dt(&config->gpio_start_sync, 1);
923
924 if (result != 0) {
925 LOG_ERR("unable to start ADC operation");
926 return result;
927 }
928
929 k_sleep(K_USEC(ADS114S0X_START_SYNC_PULSE_DURATION_IN_US +
930 ADS114S0X_SETUP_TIME_IN_US));
931
932 result = gpio_pin_set_dt(&config->gpio_start_sync, 0);
933
934 if (result != 0) {
935 LOG_ERR("unable to start ADC operation");
936 return result;
937 }
938 }
939
940 return 0;
941 }
942
ads114s0x_wait_data_ready(const struct device * dev)943 static int ads114s0x_wait_data_ready(const struct device *dev)
944 {
945 struct ads114s0x_data *data = dev->data;
946
947 return k_sem_take(&data->data_ready_signal, ADC_CONTEXT_WAIT_FOR_COMPLETION_TIMEOUT);
948 }
949
ads114s0x_read_sample(const struct device * dev,uint16_t * buffer)950 static int ads114s0x_read_sample(const struct device *dev, uint16_t *buffer)
951 {
952 const struct ads114s0x_config *config = dev->config;
953 uint8_t buffer_tx[3];
954 uint8_t buffer_rx[ARRAY_SIZE(buffer_tx)];
955 const struct spi_buf tx_buf[] = {{
956 .buf = buffer_tx,
957 .len = ARRAY_SIZE(buffer_tx),
958 }};
959 const struct spi_buf rx_buf[] = {{
960 .buf = buffer_rx,
961 .len = ARRAY_SIZE(buffer_rx),
962 }};
963 const struct spi_buf_set tx = {
964 .buffers = tx_buf,
965 .count = ARRAY_SIZE(tx_buf),
966 };
967 const struct spi_buf_set rx = {
968 .buffers = rx_buf,
969 .count = ARRAY_SIZE(rx_buf),
970 };
971
972 buffer_tx[0] = (uint8_t)ADS114S0X_COMMAND_RDATA;
973
974 int result = spi_transceive_dt(&config->bus, &tx, &rx);
975
976 if (result != 0) {
977 LOG_ERR("spi_transceive failed with error %i", result);
978 return result;
979 }
980
981 *buffer = sys_get_be16(buffer_rx + 1);
982
983 return 0;
984 }
985
ads114s0x_adc_perform_read(const struct device * dev)986 static int ads114s0x_adc_perform_read(const struct device *dev)
987 {
988 int result;
989 struct ads114s0x_data *data = dev->data;
990
991 k_sem_take(&data->acquire_signal, K_FOREVER);
992
993 result = ads114s0x_send_start_read(dev);
994 if (result != 0) {
995 LOG_ERR("unable to start ADC conversion");
996 adc_context_complete(&data->ctx, result);
997 return result;
998 }
999
1000 result = ads114s0x_wait_data_ready(dev);
1001 if (result != 0) {
1002 LOG_ERR("waiting for data to be ready failed");
1003 adc_context_complete(&data->ctx, result);
1004 return result;
1005 }
1006
1007 result = ads114s0x_read_sample(dev, data->buffer);
1008 if (result != 0) {
1009 LOG_ERR("reading sample failed");
1010 adc_context_complete(&data->ctx, result);
1011 return result;
1012 }
1013
1014 data->buffer++;
1015
1016 adc_context_on_sampling_done(&data->ctx, dev);
1017
1018 return result;
1019 }
1020
1021 #if CONFIG_ADC_ASYNC
ads114s0x_adc_read_async(const struct device * dev,const struct adc_sequence * sequence,struct k_poll_signal * async)1022 static int ads114s0x_adc_read_async(const struct device *dev, const struct adc_sequence *sequence,
1023 struct k_poll_signal *async)
1024 {
1025 int result;
1026 struct ads114s0x_data *data = dev->data;
1027
1028 adc_context_lock(&data->ctx, true, async);
1029 result = ads114s0x_adc_start_read(dev, sequence, true);
1030 adc_context_release(&data->ctx, result);
1031
1032 return result;
1033 }
1034
ads114s0x_read(const struct device * dev,const struct adc_sequence * sequence)1035 static int ads114s0x_read(const struct device *dev, const struct adc_sequence *sequence)
1036 {
1037 int result;
1038 struct ads114s0x_data *data = dev->data;
1039
1040 adc_context_lock(&data->ctx, false, NULL);
1041 result = ads114s0x_adc_start_read(dev, sequence, true);
1042 adc_context_release(&data->ctx, result);
1043
1044 return result;
1045 }
1046
1047 #else
ads114s0x_read(const struct device * dev,const struct adc_sequence * sequence)1048 static int ads114s0x_read(const struct device *dev, const struct adc_sequence *sequence)
1049 {
1050 int result;
1051 struct ads114s0x_data *data = dev->data;
1052
1053 adc_context_lock(&data->ctx, false, NULL);
1054 result = ads114s0x_adc_start_read(dev, sequence, false);
1055
1056 while (result == 0 && k_sem_take(&data->ctx.sync, K_NO_WAIT) != 0) {
1057 result = ads114s0x_adc_perform_read(dev);
1058 }
1059
1060 adc_context_release(&data->ctx, result);
1061 return result;
1062 }
1063 #endif
1064
1065 #if CONFIG_ADC_ASYNC
ads114s0x_acquisition_thread(struct device * dev)1066 static void ads114s0x_acquisition_thread(struct device *dev)
1067 {
1068 while (true) {
1069 ads114s0x_adc_perform_read(dev);
1070 }
1071 }
1072 #endif
1073
1074 #ifdef CONFIG_ADC_ADS114S0X_GPIO
ads114s0x_gpio_write_config(const struct device * dev)1075 static int ads114s0x_gpio_write_config(const struct device *dev)
1076 {
1077 struct ads114s0x_data *data = dev->data;
1078 const struct ads114s0x_config *config = dev->config;
1079 uint8_t register_addresses[2];
1080 uint8_t register_values[ARRAY_SIZE(register_addresses)];
1081 uint8_t gpio_dat = 0;
1082 uint8_t gpio_con = 0;
1083
1084 ADS114S0X_REGISTER_GPIOCON_CON_SET(gpio_con, data->gpio_enabled);
1085 ADS114S0X_REGISTER_GPIODAT_DAT_SET(gpio_dat, data->gpio_value);
1086 ADS114S0X_REGISTER_GPIODAT_DIR_SET(gpio_dat, data->gpio_direction);
1087
1088 register_values[0] = gpio_dat;
1089 register_values[1] = gpio_con;
1090 register_addresses[0] = ADS114S0X_REGISTER_GPIODAT;
1091 register_addresses[1] = ADS114S0X_REGISTER_GPIOCON;
1092 return ads114s0x_write_multiple_registers(&config->bus, register_addresses, register_values,
1093 ARRAY_SIZE(register_values));
1094 }
1095
ads114s0x_gpio_write_value(const struct device * dev)1096 static int ads114s0x_gpio_write_value(const struct device *dev)
1097 {
1098 struct ads114s0x_data *data = dev->data;
1099 const struct ads114s0x_config *config = dev->config;
1100 uint8_t gpio_dat = 0;
1101
1102 ADS114S0X_REGISTER_GPIODAT_DAT_SET(gpio_dat, data->gpio_value);
1103 ADS114S0X_REGISTER_GPIODAT_DIR_SET(gpio_dat, data->gpio_direction);
1104
1105 return ads114s0x_write_register(&config->bus, ADS114S0X_REGISTER_GPIODAT, gpio_dat);
1106 }
1107
ads114s0x_gpio_set_output(const struct device * dev,uint8_t pin,bool initial_value)1108 int ads114s0x_gpio_set_output(const struct device *dev, uint8_t pin, bool initial_value)
1109 {
1110 struct ads114s0x_data *data = dev->data;
1111 int result = 0;
1112
1113 if (pin > ADS114S0X_GPIO_MAX) {
1114 LOG_ERR("invalid pin %i", pin);
1115 return -EINVAL;
1116 }
1117
1118 k_mutex_lock(&data->gpio_lock, K_FOREVER);
1119
1120 data->gpio_enabled |= BIT(pin);
1121 data->gpio_direction &= ~BIT(pin);
1122
1123 if (initial_value) {
1124 data->gpio_value |= BIT(pin);
1125 } else {
1126 data->gpio_value &= ~BIT(pin);
1127 }
1128
1129 result = ads114s0x_gpio_write_config(dev);
1130
1131 k_mutex_unlock(&data->gpio_lock);
1132
1133 return result;
1134 }
1135
ads114s0x_gpio_set_input(const struct device * dev,uint8_t pin)1136 int ads114s0x_gpio_set_input(const struct device *dev, uint8_t pin)
1137 {
1138 struct ads114s0x_data *data = dev->data;
1139 int result = 0;
1140
1141 if (pin > ADS114S0X_GPIO_MAX) {
1142 LOG_ERR("invalid pin %i", pin);
1143 return -EINVAL;
1144 }
1145
1146 k_mutex_lock(&data->gpio_lock, K_FOREVER);
1147
1148 data->gpio_enabled |= BIT(pin);
1149 data->gpio_direction |= BIT(pin);
1150 data->gpio_value &= ~BIT(pin);
1151
1152 result = ads114s0x_gpio_write_config(dev);
1153
1154 k_mutex_unlock(&data->gpio_lock);
1155
1156 return result;
1157 }
1158
ads114s0x_gpio_deconfigure(const struct device * dev,uint8_t pin)1159 int ads114s0x_gpio_deconfigure(const struct device *dev, uint8_t pin)
1160 {
1161 struct ads114s0x_data *data = dev->data;
1162 int result = 0;
1163
1164 if (pin > ADS114S0X_GPIO_MAX) {
1165 LOG_ERR("invalid pin %i", pin);
1166 return -EINVAL;
1167 }
1168
1169 k_mutex_lock(&data->gpio_lock, K_FOREVER);
1170
1171 data->gpio_enabled &= ~BIT(pin);
1172 data->gpio_direction |= BIT(pin);
1173 data->gpio_value &= ~BIT(pin);
1174
1175 result = ads114s0x_gpio_write_config(dev);
1176
1177 k_mutex_unlock(&data->gpio_lock);
1178
1179 return result;
1180 }
1181
ads114s0x_gpio_set_pin_value(const struct device * dev,uint8_t pin,bool value)1182 int ads114s0x_gpio_set_pin_value(const struct device *dev, uint8_t pin, bool value)
1183 {
1184 struct ads114s0x_data *data = dev->data;
1185 int result = 0;
1186
1187 if (pin > ADS114S0X_GPIO_MAX) {
1188 LOG_ERR("invalid pin %i", pin);
1189 return -EINVAL;
1190 }
1191
1192 k_mutex_lock(&data->gpio_lock, K_FOREVER);
1193
1194 if ((BIT(pin) & data->gpio_enabled) == 0) {
1195 LOG_ERR("gpio pin %i not configured", pin);
1196 result = -EINVAL;
1197 } else if ((BIT(pin) & data->gpio_direction) != 0) {
1198 LOG_ERR("gpio pin %i not configured as output", pin);
1199 result = -EINVAL;
1200 } else {
1201 data->gpio_value |= BIT(pin);
1202
1203 result = ads114s0x_gpio_write_value(dev);
1204 }
1205
1206 k_mutex_unlock(&data->gpio_lock);
1207
1208 return result;
1209 }
1210
ads114s0x_gpio_get_pin_value(const struct device * dev,uint8_t pin,bool * value)1211 int ads114s0x_gpio_get_pin_value(const struct device *dev, uint8_t pin, bool *value)
1212 {
1213 struct ads114s0x_data *data = dev->data;
1214 const struct ads114s0x_config *config = dev->config;
1215 int result = 0;
1216 uint8_t gpio_dat;
1217
1218 if (pin > ADS114S0X_GPIO_MAX) {
1219 LOG_ERR("invalid pin %i", pin);
1220 return -EINVAL;
1221 }
1222
1223 k_mutex_lock(&data->gpio_lock, K_FOREVER);
1224
1225 if ((BIT(pin) & data->gpio_enabled) == 0) {
1226 LOG_ERR("gpio pin %i not configured", pin);
1227 result = -EINVAL;
1228 } else if ((BIT(pin) & data->gpio_direction) == 0) {
1229 LOG_ERR("gpio pin %i not configured as input", pin);
1230 result = -EINVAL;
1231 } else {
1232 result = ads114s0x_read_register(&config->bus, ADS114S0X_REGISTER_GPIODAT,
1233 &gpio_dat);
1234 data->gpio_value = ADS114S0X_REGISTER_GPIODAT_DAT_GET(gpio_dat);
1235 *value = (BIT(pin) & data->gpio_value) != 0;
1236 }
1237
1238 k_mutex_unlock(&data->gpio_lock);
1239
1240 return result;
1241 }
1242
ads114s0x_gpio_port_get_raw(const struct device * dev,gpio_port_value_t * value)1243 int ads114s0x_gpio_port_get_raw(const struct device *dev, gpio_port_value_t *value)
1244 {
1245 struct ads114s0x_data *data = dev->data;
1246 const struct ads114s0x_config *config = dev->config;
1247 int result = 0;
1248 uint8_t gpio_dat;
1249
1250 k_mutex_lock(&data->gpio_lock, K_FOREVER);
1251
1252 result = ads114s0x_read_register(&config->bus, ADS114S0X_REGISTER_GPIODAT, &gpio_dat);
1253 data->gpio_value = ADS114S0X_REGISTER_GPIODAT_DAT_GET(gpio_dat);
1254 *value = data->gpio_value;
1255
1256 k_mutex_unlock(&data->gpio_lock);
1257
1258 return result;
1259 }
1260
ads114s0x_gpio_port_set_masked_raw(const struct device * dev,gpio_port_pins_t mask,gpio_port_value_t value)1261 int ads114s0x_gpio_port_set_masked_raw(const struct device *dev, gpio_port_pins_t mask,
1262 gpio_port_value_t value)
1263 {
1264 struct ads114s0x_data *data = dev->data;
1265 int result = 0;
1266
1267 k_mutex_lock(&data->gpio_lock, K_FOREVER);
1268
1269 data->gpio_value = ((data->gpio_value & ~mask) | (mask & value)) & data->gpio_enabled &
1270 ~data->gpio_direction;
1271 result = ads114s0x_gpio_write_value(dev);
1272
1273 k_mutex_unlock(&data->gpio_lock);
1274
1275 return result;
1276 }
1277
ads114s0x_gpio_port_toggle_bits(const struct device * dev,gpio_port_pins_t pins)1278 int ads114s0x_gpio_port_toggle_bits(const struct device *dev, gpio_port_pins_t pins)
1279 {
1280 struct ads114s0x_data *data = dev->data;
1281 int result = 0;
1282
1283 k_mutex_lock(&data->gpio_lock, K_FOREVER);
1284
1285 data->gpio_value = (data->gpio_value ^ pins) & data->gpio_enabled & ~data->gpio_direction;
1286 result = ads114s0x_gpio_write_value(dev);
1287
1288 k_mutex_unlock(&data->gpio_lock);
1289
1290 return result;
1291 }
1292
1293 #endif /* CONFIG_ADC_ADS114S0X_GPIO */
1294
ads114s0x_init(const struct device * dev)1295 static int ads114s0x_init(const struct device *dev)
1296 {
1297 uint8_t status = 0;
1298 uint8_t reference_control = 0;
1299 uint8_t reference_control_read;
1300 int result;
1301 const struct ads114s0x_config *config = dev->config;
1302 struct ads114s0x_data *data = dev->data;
1303
1304 adc_context_init(&data->ctx);
1305
1306 k_sem_init(&data->data_ready_signal, 0, 1);
1307 k_sem_init(&data->acquire_signal, 0, 1);
1308
1309 #ifdef CONFIG_ADC_ADS114S0X_GPIO
1310 k_mutex_init(&data->gpio_lock);
1311 #endif /* CONFIG_ADC_ADS114S0X_GPIO */
1312
1313 if (!spi_is_ready_dt(&config->bus)) {
1314 LOG_ERR("SPI device is not ready");
1315 return -ENODEV;
1316 }
1317
1318 if (config->gpio_reset.port != NULL) {
1319 result = gpio_pin_configure_dt(&config->gpio_reset, GPIO_OUTPUT_ACTIVE);
1320 if (result != 0) {
1321 LOG_ERR("failed to initialize GPIO for reset");
1322 return result;
1323 }
1324 }
1325
1326 if (config->gpio_start_sync.port != NULL) {
1327 result = gpio_pin_configure_dt(&config->gpio_start_sync, GPIO_OUTPUT_INACTIVE);
1328 if (result != 0) {
1329 LOG_ERR("failed to initialize GPIO for start/sync");
1330 return result;
1331 }
1332 }
1333
1334 result = gpio_pin_configure_dt(&config->gpio_data_ready, GPIO_INPUT);
1335 if (result != 0) {
1336 LOG_ERR("failed to initialize GPIO for data ready");
1337 return result;
1338 }
1339
1340 result = gpio_pin_interrupt_configure_dt(&config->gpio_data_ready, GPIO_INT_EDGE_TO_ACTIVE);
1341 if (result != 0) {
1342 LOG_ERR("failed to configure data ready interrupt");
1343 return -EIO;
1344 }
1345
1346 gpio_init_callback(&data->callback_data_ready, ads114s0x_data_ready_handler,
1347 BIT(config->gpio_data_ready.pin));
1348 result = gpio_add_callback(config->gpio_data_ready.port, &data->callback_data_ready);
1349 if (result != 0) {
1350 LOG_ERR("failed to add data ready callback");
1351 return -EIO;
1352 }
1353
1354 #if CONFIG_ADC_ASYNC
1355 const k_tid_t tid = k_thread_create(
1356 &data->thread, config->stack, CONFIG_ADC_ADS114S0X_ACQUISITION_THREAD_STACK_SIZE,
1357 (k_thread_entry_t)ads114s0x_acquisition_thread, (void *)dev, NULL, NULL,
1358 CONFIG_ADC_ADS114S0X_ASYNC_THREAD_INIT_PRIO, 0, K_NO_WAIT);
1359 k_thread_name_set(tid, "adc_ads114s0x");
1360 #endif
1361
1362 k_busy_wait(ADS114S0X_POWER_ON_RESET_TIME_IN_US);
1363
1364 if (config->gpio_reset.port == NULL) {
1365 result = ads114s0x_send_command(&config->bus, ADS114S0X_COMMAND_RESET);
1366 if (result != 0) {
1367 LOG_ERR("unable to send RESET command");
1368 return result;
1369 }
1370 } else {
1371 k_busy_wait(ADS114S0X_RESET_LOW_TIME_IN_US);
1372 gpio_pin_set_dt(&config->gpio_reset, 0);
1373 }
1374
1375 k_busy_wait(ADS114S0X_RESET_DELAY_TIME_IN_US);
1376
1377 result = ads114s0x_read_register(&config->bus, ADS114S0X_REGISTER_STATUS, &status);
1378 if (result != 0) {
1379 LOG_ERR("unable to read status register");
1380 return result;
1381 }
1382
1383 if (ADS114S0X_REGISTER_STATUS_NOT_RDY_GET(status) == 0x01) {
1384 LOG_ERR("ADS114 is not yet ready");
1385 return -EBUSY;
1386 }
1387
1388 /*
1389 * Activate internal voltage reference during initialization to
1390 * avoid the necessary setup time for it to settle later on.
1391 */
1392 ADS114S0X_REGISTER_REF_SET_DEFAULTS(reference_control);
1393
1394 result = ads114s0x_write_register(&config->bus, ADS114S0X_REGISTER_REF, reference_control);
1395 if (result != 0) {
1396 LOG_ERR("unable to set default reference control values");
1397 return result;
1398 }
1399
1400 /*
1401 * Ensure that the internal voltage reference is active.
1402 */
1403 result = ads114s0x_read_register(&config->bus, ADS114S0X_REGISTER_REF,
1404 &reference_control_read);
1405 if (result != 0) {
1406 LOG_ERR("unable to read reference control values");
1407 return result;
1408 }
1409
1410 if (reference_control != reference_control_read) {
1411 LOG_ERR("reference control register is incorrect: 0x%02X", reference_control_read);
1412 return -EIO;
1413 }
1414
1415 #ifdef CONFIG_ADC_ADS114S0X_GPIO
1416 data->gpio_enabled = 0x00;
1417 data->gpio_direction = 0x0F;
1418 data->gpio_value = 0x00;
1419
1420 result = ads114s0x_gpio_write_config(dev);
1421
1422 if (result != 0) {
1423 LOG_ERR("unable to configure defaults for GPIOs");
1424 return result;
1425 }
1426 #endif
1427
1428 adc_context_unlock_unconditionally(&data->ctx);
1429
1430 return result;
1431 }
1432
1433 static const struct adc_driver_api api = {
1434 .channel_setup = ads114s0x_channel_setup,
1435 .read = ads114s0x_read,
1436 .ref_internal = ADS114S0X_REF_INTERNAL,
1437 #ifdef CONFIG_ADC_ASYNC
1438 .read_async = ads114s0x_adc_read_async,
1439 #endif
1440 };
1441
1442 BUILD_ASSERT(CONFIG_ADC_INIT_PRIORITY > CONFIG_SPI_INIT_PRIORITY,
1443 "CONFIG_ADC_INIT_PRIORITY must be higher than CONFIG_SPI_INIT_PRIORITY");
1444
1445 #define DT_DRV_COMPAT ti_ads114s08
1446
1447 #define ADC_ADS114S0X_INST_DEFINE(n) \
1448 IF_ENABLED( \
1449 CONFIG_ADC_ASYNC, \
1450 (static K_KERNEL_STACK_DEFINE( \
1451 thread_stack_##n, CONFIG_ADC_ADS114S0X_ACQUISITION_THREAD_STACK_SIZE);)) \
1452 static const struct ads114s0x_config config_##n = { \
1453 .bus = SPI_DT_SPEC_INST_GET( \
1454 n, SPI_OP_MODE_MASTER | SPI_MODE_CPHA | SPI_WORD_SET(8), 0), \
1455 IF_ENABLED(CONFIG_ADC_ASYNC, (.stack = thread_stack_##n,)) \
1456 .gpio_reset = GPIO_DT_SPEC_INST_GET_OR(n, reset_gpios, {0}), \
1457 .gpio_data_ready = GPIO_DT_SPEC_INST_GET(n, drdy_gpios), \
1458 .gpio_start_sync = GPIO_DT_SPEC_INST_GET_OR(n, start_sync_gpios, {0}), \
1459 .idac_current = DT_INST_PROP(n, idac_current), \
1460 }; \
1461 static struct ads114s0x_data data_##n; \
1462 DEVICE_DT_INST_DEFINE(n, ads114s0x_init, NULL, &data_##n, &config_##n, POST_KERNEL, \
1463 CONFIG_ADC_INIT_PRIORITY, &api);
1464
1465 DT_INST_FOREACH_STATUS_OKAY(ADC_ADS114S0X_INST_DEFINE);
1466