1 /**
2  * @file
3  * @brief ADC public API header file.
4  */
5 
6 /*
7  * Copyright (c) 2018 Nordic Semiconductor ASA
8  * Copyright (c) 2015 Intel Corporation
9  *
10  * SPDX-License-Identifier: Apache-2.0
11  */
12 
13 #ifndef ZEPHYR_INCLUDE_DRIVERS_ADC_H_
14 #define ZEPHYR_INCLUDE_DRIVERS_ADC_H_
15 
16 #include <zephyr/device.h>
17 #include <zephyr/dt-bindings/adc/adc.h>
18 #include <zephyr/kernel.h>
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23 
24 /**
25  * @brief ADC driver APIs
26  * @defgroup adc_interface ADC driver APIs
27  * @ingroup io_interfaces
28  * @{
29  */
30 
31 /** @brief ADC channel gain factors. */
32 enum adc_gain {
33 	ADC_GAIN_1_6, /**< x 1/6. */
34 	ADC_GAIN_1_5, /**< x 1/5. */
35 	ADC_GAIN_1_4, /**< x 1/4. */
36 	ADC_GAIN_1_3, /**< x 1/3. */
37 	ADC_GAIN_2_5, /**< x 2/5. */
38 	ADC_GAIN_1_2, /**< x 1/2. */
39 	ADC_GAIN_2_3, /**< x 2/3. */
40 	ADC_GAIN_4_5, /**< x 4/5. */
41 	ADC_GAIN_1,   /**< x 1. */
42 	ADC_GAIN_2,   /**< x 2. */
43 	ADC_GAIN_3,   /**< x 3. */
44 	ADC_GAIN_4,   /**< x 4. */
45 	ADC_GAIN_6,   /**< x 6. */
46 	ADC_GAIN_8,   /**< x 8. */
47 	ADC_GAIN_12,  /**< x 12. */
48 	ADC_GAIN_16,  /**< x 16. */
49 	ADC_GAIN_24,  /**< x 24. */
50 	ADC_GAIN_32,  /**< x 32. */
51 	ADC_GAIN_64,  /**< x 64. */
52 	ADC_GAIN_128, /**< x 128. */
53 };
54 
55 /**
56  * @brief Invert the application of gain to a measurement value.
57  *
58  * For example, if the gain passed in is ADC_GAIN_1_6 and the
59  * referenced value is 10, the value after the function returns is 60.
60  *
61  * @param gain the gain used to amplify the input signal.
62  *
63  * @param value a pointer to a value that initially has the effect of
64  * the applied gain but has that effect removed when this function
65  * successfully returns.  If the gain cannot be reversed the value
66  * remains unchanged.
67  *
68  * @retval 0 if the gain was successfully reversed
69  * @retval -EINVAL if the gain could not be interpreted
70  */
71 int adc_gain_invert(enum adc_gain gain,
72 		    int32_t *value);
73 
74 /** @brief ADC references. */
75 enum adc_reference {
76 	ADC_REF_VDD_1,     /**< VDD. */
77 	ADC_REF_VDD_1_2,   /**< VDD/2. */
78 	ADC_REF_VDD_1_3,   /**< VDD/3. */
79 	ADC_REF_VDD_1_4,   /**< VDD/4. */
80 	ADC_REF_INTERNAL,  /**< Internal. */
81 	ADC_REF_EXTERNAL0, /**< External, input 0. */
82 	ADC_REF_EXTERNAL1, /**< External, input 1. */
83 };
84 
85 /**
86  * @brief Structure for specifying the configuration of an ADC channel.
87  */
88 struct adc_channel_cfg {
89 	/** Gain selection. */
90 	enum adc_gain gain;
91 
92 	/** Reference selection. */
93 	enum adc_reference reference;
94 
95 	/**
96 	 * Acquisition time.
97 	 * Use the ADC_ACQ_TIME macro to compose the value for this field or
98 	 * pass ADC_ACQ_TIME_DEFAULT to use the default setting for a given
99 	 * hardware (e.g. when the hardware does not allow to configure the
100 	 * acquisition time).
101 	 * Particular drivers do not necessarily support all the possible units.
102 	 * Value range is 0-16383 for a given unit.
103 	 */
104 	uint16_t acquisition_time;
105 
106 	/**
107 	 * Channel identifier.
108 	 * This value primarily identifies the channel within the ADC API - when
109 	 * a read request is done, the corresponding bit in the "channels" field
110 	 * of the "adc_sequence" structure must be set to include this channel
111 	 * in the sampling.
112 	 * For hardware that does not allow selection of analog inputs for given
113 	 * channels, but rather have dedicated ones, this value also selects the
114 	 * physical ADC input to be used in the sampling. Otherwise, when it is
115 	 * needed to explicitly select an analog input for the channel, or two
116 	 * inputs when the channel is a differential one, the selection is done
117 	 * in "input_positive" and "input_negative" fields.
118 	 * Particular drivers indicate which one of the above two cases they
119 	 * support by selecting or not a special hidden Kconfig option named
120 	 * ADC_CONFIGURABLE_INPUTS. If this option is not selected, the macro
121 	 * CONFIG_ADC_CONFIGURABLE_INPUTS is not defined and consequently the
122 	 * mentioned two fields are not present in this structure.
123 	 * While this API allows identifiers from range 0-31, particular drivers
124 	 * may support only a limited number of channel identifiers (dependent
125 	 * on the underlying hardware capabilities or configured via a dedicated
126 	 * Kconfig option).
127 	 */
128 	uint8_t channel_id   : 5;
129 
130 	/** Channel type: single-ended or differential. */
131 	uint8_t differential : 1;
132 
133 #ifdef CONFIG_ADC_CONFIGURABLE_INPUTS
134 	/**
135 	 * Positive ADC input.
136 	 * This is a driver dependent value that identifies an ADC input to be
137 	 * associated with the channel.
138 	 */
139 	uint8_t input_positive;
140 
141 	/**
142 	 * Negative ADC input (used only for differential channels).
143 	 * This is a driver dependent value that identifies an ADC input to be
144 	 * associated with the channel.
145 	 */
146 	uint8_t input_negative;
147 #endif /* CONFIG_ADC_CONFIGURABLE_INPUTS */
148 
149 #ifdef CONFIG_ADC_CONFIGURABLE_EXCITATION_CURRENT_SOURCE_PIN
150 	uint8_t current_source_pin_set : 1;
151 	/**
152 	 * Output pin for the current sources.
153 	 * This is only available if the driver enables this feature
154 	 * via the hidden configuration option ADC_CONFIGURABLE_EXCITATION_CURRENT_SOURCE_PIN.
155 	 * The meaning itself is then defined by the driver itself.
156 	 */
157 	uint8_t current_source_pin[2];
158 #endif /* CONFIG_ADC_CONFIGURABLE_EXCITATION_CURRENT_SOURCE_PIN */
159 };
160 
161 /**
162  * @brief Get ADC channel configuration from a given devicetree node.
163  *
164  * This returns a static initializer for a <tt>struct adc_channel_cfg</tt>
165  * filled with data from a given devicetree node.
166  *
167  * Example devicetree fragment:
168  *
169  * @code{.dts}
170  * &adc {
171  *    #address-cells = <1>;
172  *    #size-cells = <0>;
173  *
174  *    channel@0 {
175  *        reg = <0>;
176  *        zephyr,gain = "ADC_GAIN_1_6";
177  *        zephyr,reference = "ADC_REF_INTERNAL";
178  *        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 20)>;
179  *        zephyr,input-positive = <NRF_SAADC_AIN6>;
180  *        zephyr,input-negative = <NRF_SAADC_AIN7>;
181  *    };
182  *
183  *    channel@1 {
184  *        reg = <1>;
185  *        zephyr,gain = "ADC_GAIN_1_6";
186  *        zephyr,reference = "ADC_REF_INTERNAL";
187  *        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
188  *        zephyr,input-positive = <NRF_SAADC_AIN0>;
189  *    };
190  * };
191  * @endcode
192  *
193  * Example usage:
194  *
195  * @code{.c}
196  * static const struct adc_channel_cfg ch0_cfg_dt =
197  *     ADC_CHANNEL_CFG_DT(DT_CHILD(DT_NODELABEL(adc), channel_0));
198  * static const struct adc_channel_cfg ch1_cfg_dt =
199  *     ADC_CHANNEL_CFG_DT(DT_CHILD(DT_NODELABEL(adc), channel_1));
200  *
201  * // Initializes 'ch0_cfg_dt' to:
202  * // {
203  * //     .channel_id = 0,
204  * //     .gain = ADC_GAIN_1_6,
205  * //     .reference = ADC_REF_INTERNAL,
206  * //     .acquisition_time = ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 20),
207  * //     .differential = true,
208  * //     .input_positive = NRF_SAADC_AIN6,
209  * //     .input-negative = NRF_SAADC_AIN7,
210  * // }
211  * // and 'ch1_cfg_dt' to:
212  * // {
213  * //     .channel_id = 1,
214  * //     .gain = ADC_GAIN_1_6,
215  * //     .reference = ADC_REF_INTERNAL,
216  * //     .acquisition_time = ADC_ACQ_TIME_DEFAULT,
217  * //     .input_positive = NRF_SAADC_AIN0,
218  * // }
219  * @endcode
220  *
221  * @param node_id Devicetree node identifier.
222  *
223  * @return Static initializer for an adc_channel_cfg structure.
224  */
225 #define ADC_CHANNEL_CFG_DT(node_id) { \
226 	.gain             = DT_STRING_TOKEN(node_id, zephyr_gain), \
227 	.reference        = DT_STRING_TOKEN(node_id, zephyr_reference), \
228 	.acquisition_time = DT_PROP(node_id, zephyr_acquisition_time), \
229 	.channel_id       = DT_REG_ADDR(node_id), \
230 IF_ENABLED(CONFIG_ADC_CONFIGURABLE_INPUTS, \
231 	(.differential    = DT_NODE_HAS_PROP(node_id, zephyr_input_negative), \
232 	 .input_positive  = DT_PROP_OR(node_id, zephyr_input_positive, 0), \
233 	 .input_negative  = DT_PROP_OR(node_id, zephyr_input_negative, 0),)) \
234 IF_ENABLED(CONFIG_ADC_CONFIGURABLE_EXCITATION_CURRENT_SOURCE_PIN, \
235 	(.current_source_pin_set = DT_NODE_HAS_PROP(node_id, zephyr_current_source_pin), \
236 	 .current_source_pin = DT_PROP_OR(node_id, zephyr_current_source_pin, {0}),)) \
237 }
238 
239 /**
240  * @brief Container for ADC channel information specified in devicetree.
241  *
242  * @see ADC_DT_SPEC_GET_BY_IDX
243  * @see ADC_DT_SPEC_GET
244  */
245 struct adc_dt_spec {
246 	/**
247 	 * Pointer to the device structure for the ADC driver instance
248 	 * used by this io-channel.
249 	 */
250 	const struct device *dev;
251 
252 	/** ADC channel identifier used by this io-channel. */
253 	uint8_t channel_id;
254 
255 	/**
256 	 * Flag indicating whether configuration of the associated ADC channel
257 	 * is provided as a child node of the corresponding ADC controller in
258 	 * devicetree.
259 	 */
260 	bool channel_cfg_dt_node_exists;
261 
262 	/**
263 	 * Configuration of the associated ADC channel specified in devicetree.
264 	 * This field is valid only when @a channel_cfg_dt_node_exists is set
265 	 * to @a true.
266 	 */
267 	struct adc_channel_cfg channel_cfg;
268 
269 	/**
270 	 * Voltage of the reference selected for the channel or 0 if this
271 	 * value is not provided in devicetree.
272 	 * This field is valid only when @a channel_cfg_dt_node_exists is set
273 	 * to @a true.
274 	 */
275 	uint16_t vref_mv;
276 
277 	/**
278 	 * ADC resolution to be used for that channel.
279 	 * This field is valid only when @a channel_cfg_dt_node_exists is set
280 	 * to @a true.
281 	 */
282 	uint8_t resolution;
283 
284 	/**
285 	 * Oversampling setting to be used for that channel.
286 	 * This field is valid only when @a channel_cfg_dt_node_exists is set
287 	 * to @a true.
288 	 */
289 	uint8_t oversampling;
290 };
291 
292 /** @cond INTERNAL_HIDDEN */
293 
294 #define ADC_DT_SPEC_STRUCT(ctlr, input) { \
295 		.dev = DEVICE_DT_GET(ctlr), \
296 		.channel_id = input, \
297 		ADC_CHANNEL_CFG_FROM_DT_NODE(\
298 			ADC_CHANNEL_DT_NODE(ctlr, input)) \
299 	}
300 
301 #define ADC_CHANNEL_DT_NODE(ctlr, input) \
302 	DT_FOREACH_CHILD_VARGS(ctlr, ADC_FOREACH_INPUT, input)
303 
304 #define ADC_FOREACH_INPUT(node, input) \
305 	IF_ENABLED(IS_EQ(DT_REG_ADDR(node), input), (node))
306 
307 #define ADC_CHANNEL_CFG_FROM_DT_NODE(node_id) \
308 	IF_ENABLED(DT_NODE_EXISTS(node_id), \
309 		(.channel_cfg_dt_node_exists = true, \
310 		 .channel_cfg  = ADC_CHANNEL_CFG_DT(node_id), \
311 		 .vref_mv      = DT_PROP_OR(node_id, zephyr_vref_mv, 0), \
312 		 .resolution   = DT_PROP_OR(node_id, zephyr_resolution, 0), \
313 		 .oversampling = DT_PROP_OR(node_id, zephyr_oversampling, 0),))
314 
315 /** @endcond */
316 
317 /**
318  * @brief Get ADC io-channel information from devicetree.
319  *
320  * This returns a static initializer for an @p adc_dt_spec structure
321  * given a devicetree node and a channel index. The node must have
322  * the "io-channels" property defined.
323  *
324  * Example devicetree fragment:
325  *
326  * @code{.dts}
327  * / {
328  *     zephyr,user {
329  *         io-channels = <&adc0 1>, <&adc0 3>;
330  *     };
331  * };
332  *
333  * &adc0 {
334  *    #address-cells = <1>;
335  *    #size-cells = <0>;
336  *
337  *    channel@3 {
338  *        reg = <3>;
339  *        zephyr,gain = "ADC_GAIN_1_5";
340  *        zephyr,reference = "ADC_REF_VDD_1_4";
341  *        zephyr,vref-mv = <750>;
342  *        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
343  *        zephyr,resolution = <12>;
344  *        zephyr,oversampling = <4>;
345  *    };
346  * };
347  * @endcode
348  *
349  * Example usage:
350  *
351  * @code{.c}
352  * static const struct adc_dt_spec adc_chan0 =
353  *     ADC_DT_SPEC_GET_BY_IDX(DT_PATH(zephyr_user), 0);
354  * static const struct adc_dt_spec adc_chan1 =
355  *     ADC_DT_SPEC_GET_BY_IDX(DT_PATH(zephyr_user), 1);
356  *
357  * // Initializes 'adc_chan0' to:
358  * // {
359  * //     .dev = DEVICE_DT_GET(DT_NODELABEL(adc0)),
360  * //     .channel_id = 1,
361  * // }
362  * // and 'adc_chan1' to:
363  * // {
364  * //     .dev = DEVICE_DT_GET(DT_NODELABEL(adc0)),
365  * //     .channel_id = 3,
366  * //     .channel_cfg_dt_node_exists = true,
367  * //     .channel_cfg = {
368  * //         .channel_id = 3,
369  * //         .gain = ADC_GAIN_1_5,
370  * //         .reference = ADC_REF_VDD_1_4,
371  * //         .acquisition_time = ADC_ACQ_TIME_DEFAULT,
372  * //     },
373  * //     .vref_mv = 750,
374  * //     .resolution = 12,
375  * //     .oversampling = 4,
376  * // }
377  * @endcode
378  *
379  * @see ADC_DT_SPEC_GET()
380  *
381  * @param node_id Devicetree node identifier.
382  * @param idx Channel index.
383  *
384  * @return Static initializer for an adc_dt_spec structure.
385  */
386 #define ADC_DT_SPEC_GET_BY_IDX(node_id, idx) \
387 	ADC_DT_SPEC_STRUCT(DT_IO_CHANNELS_CTLR_BY_IDX(node_id, idx), \
388 			   DT_IO_CHANNELS_INPUT_BY_IDX(node_id, idx))
389 
390 /** @brief Get ADC io-channel information from a DT_DRV_COMPAT devicetree
391  *         instance.
392  *
393  * @see ADC_DT_SPEC_GET_BY_IDX()
394  *
395  * @param inst DT_DRV_COMPAT instance number
396  * @param idx Channel index.
397  *
398  * @return Static initializer for an adc_dt_spec structure.
399  */
400 #define ADC_DT_SPEC_INST_GET_BY_IDX(inst, idx) \
401 	ADC_DT_SPEC_GET_BY_IDX(DT_DRV_INST(inst), idx)
402 
403 /**
404  * @brief Equivalent to ADC_DT_SPEC_GET_BY_IDX(node_id, 0).
405  *
406  * @see ADC_DT_SPEC_GET_BY_IDX()
407  *
408  * @param node_id Devicetree node identifier.
409  *
410  * @return Static initializer for an adc_dt_spec structure.
411  */
412 #define ADC_DT_SPEC_GET(node_id) ADC_DT_SPEC_GET_BY_IDX(node_id, 0)
413 
414 /** @brief Equivalent to ADC_DT_SPEC_INST_GET_BY_IDX(inst, 0).
415  *
416  * @see ADC_DT_SPEC_GET()
417  *
418  * @param inst DT_DRV_COMPAT instance number
419  *
420  * @return Static initializer for an adc_dt_spec structure.
421  */
422 #define ADC_DT_SPEC_INST_GET(inst) ADC_DT_SPEC_GET(DT_DRV_INST(inst))
423 
424 /* Forward declaration of the adc_sequence structure. */
425 struct adc_sequence;
426 
427 /**
428  * @brief Action to be performed after a sampling is done.
429  */
430 enum adc_action {
431 	/** The sequence should be continued normally. */
432 	ADC_ACTION_CONTINUE = 0,
433 
434 	/**
435 	 * The sampling should be repeated. New samples or sample should be
436 	 * read from the ADC and written in the same place as the recent ones.
437 	 */
438 	ADC_ACTION_REPEAT,
439 
440 	/** The sequence should be finished immediately. */
441 	ADC_ACTION_FINISH,
442 };
443 
444 /**
445  * @brief Type definition of the optional callback function to be called after
446  *        a requested sampling is done.
447  *
448  * @param dev             Pointer to the device structure for the driver
449  *                        instance.
450  * @param sequence        Pointer to the sequence structure that triggered
451  *                        the sampling. This parameter points to a copy of
452  *                        the structure that was supplied to the call that
453  *                        started the sampling sequence, thus it cannot be
454  *                        used with the CONTAINER_OF() macro to retrieve
455  *                        some other data associated with the sequence.
456  *                        Instead, the adc_sequence_options::user_data field
457  *                        should be used for such purpose.
458  *
459  * @param sampling_index  Index (0-65535) of the sampling done.
460  *
461  * @returns Action to be performed by the driver. See @ref adc_action.
462  */
463 typedef enum adc_action (*adc_sequence_callback)(const struct device *dev,
464 						 const struct adc_sequence *sequence,
465 						 uint16_t sampling_index);
466 
467 /**
468  * @brief Structure defining additional options for an ADC sampling sequence.
469  */
470 struct adc_sequence_options {
471 	/**
472 	 * Interval between consecutive samplings (in microseconds), 0 means
473 	 * sample as fast as possible, without involving any timer.
474 	 * The accuracy of this interval is dependent on the implementation of
475 	 * a given driver. The default routine that handles the intervals uses
476 	 * a kernel timer for this purpose, thus, it has the accuracy of the
477 	 * kernel's system clock. Particular drivers may use some dedicated
478 	 * hardware timers and achieve a better precision.
479 	 */
480 	uint32_t interval_us;
481 
482 	/**
483 	 * Callback function to be called after each sampling is done.
484 	 * Optional - set to NULL if it is not needed.
485 	 */
486 	adc_sequence_callback callback;
487 
488 	/**
489 	 * Pointer to user data. It can be used to associate the sequence
490 	 * with any other data that is needed in the callback function.
491 	 */
492 	void *user_data;
493 
494 	/**
495 	 * Number of extra samplings to perform (the total number of samplings
496 	 * is 1 + extra_samplings).
497 	 */
498 	uint16_t extra_samplings;
499 };
500 
501 /**
502  * @brief Structure defining an ADC sampling sequence.
503  */
504 struct adc_sequence {
505 	/**
506 	 * Pointer to a structure defining additional options for the sequence.
507 	 * If NULL, the sequence consists of a single sampling.
508 	 */
509 	const struct adc_sequence_options *options;
510 
511 	/**
512 	 * Bit-mask indicating the channels to be included in each sampling
513 	 * of this sequence.
514 	 * All selected channels must be configured with adc_channel_setup()
515 	 * before they are used in a sequence.
516 	 * The least significant bit corresponds to channel 0.
517 	 */
518 	uint32_t channels;
519 
520 	/**
521 	 * Pointer to a buffer where the samples are to be written. Samples
522 	 * from subsequent samplings are written sequentially in the buffer.
523 	 * The number of samples written for each sampling is determined by
524 	 * the number of channels selected in the "channels" field.
525 	 * The values written to the buffer represent a sample from each
526 	 * selected channel starting from the one with the lowest ID.
527 	 * The buffer must be of an appropriate size, taking into account
528 	 * the number of selected channels and the ADC resolution used,
529 	 * as well as the number of samplings contained in the sequence.
530 	 */
531 	void *buffer;
532 
533 	/**
534 	 * Specifies the actual size of the buffer pointed by the "buffer"
535 	 * field (in bytes). The driver must ensure that samples are not
536 	 * written beyond the limit and it must return an error if the buffer
537 	 * turns out to be not large enough to hold all the requested samples.
538 	 */
539 	size_t buffer_size;
540 
541 	/**
542 	 * ADC resolution.
543 	 * For single-ended channels the sample values are from range:
544 	 *   0 .. 2^resolution - 1,
545 	 * for differential ones:
546 	 *   - 2^(resolution-1) .. 2^(resolution-1) - 1.
547 	 */
548 	uint8_t resolution;
549 
550 	/**
551 	 * Oversampling setting.
552 	 * Each sample is averaged from 2^oversampling conversion results.
553 	 * This feature may be unsupported by a given ADC hardware, or in
554 	 * a specific mode (e.g. when sampling multiple channels).
555 	 */
556 	uint8_t oversampling;
557 
558 	/**
559 	 * Perform calibration before the reading is taken if requested.
560 	 *
561 	 * The impact of channel configuration on the calibration
562 	 * process is specific to the underlying hardware.  ADC
563 	 * implementations that do not support calibration should
564 	 * ignore this flag.
565 	 */
566 	bool calibrate;
567 };
568 
569 
570 /**
571  * @brief Type definition of ADC API function for configuring a channel.
572  * See adc_channel_setup() for argument descriptions.
573  */
574 typedef int (*adc_api_channel_setup)(const struct device *dev,
575 				     const struct adc_channel_cfg *channel_cfg);
576 
577 /**
578  * @brief Type definition of ADC API function for setting a read request.
579  * See adc_read() for argument descriptions.
580  */
581 typedef int (*adc_api_read)(const struct device *dev,
582 			    const struct adc_sequence *sequence);
583 
584 /**
585  * @brief Type definition of ADC API function for setting an asynchronous
586  *        read request.
587  * See adc_read_async() for argument descriptions.
588  */
589 typedef int (*adc_api_read_async)(const struct device *dev,
590 				  const struct adc_sequence *sequence,
591 				  struct k_poll_signal *async);
592 
593 /**
594  * @brief ADC driver API
595  *
596  * This is the mandatory API any ADC driver needs to expose.
597  */
598 __subsystem struct adc_driver_api {
599 	adc_api_channel_setup channel_setup;
600 	adc_api_read          read;
601 #ifdef CONFIG_ADC_ASYNC
602 	adc_api_read_async    read_async;
603 #endif
604 	uint16_t ref_internal;	/* mV */
605 };
606 
607 /**
608  * @brief Configure an ADC channel.
609  *
610  * It is required to call this function and configure each channel before it is
611  * selected for a read request.
612  *
613  * @param dev          Pointer to the device structure for the driver instance.
614  * @param channel_cfg  Channel configuration.
615  *
616  * @retval 0       On success.
617  * @retval -EINVAL If a parameter with an invalid value has been provided.
618  */
619 __syscall int adc_channel_setup(const struct device *dev,
620 				const struct adc_channel_cfg *channel_cfg);
621 
z_impl_adc_channel_setup(const struct device * dev,const struct adc_channel_cfg * channel_cfg)622 static inline int z_impl_adc_channel_setup(const struct device *dev,
623 					   const struct adc_channel_cfg *channel_cfg)
624 {
625 	const struct adc_driver_api *api =
626 				(const struct adc_driver_api *)dev->api;
627 
628 	return api->channel_setup(dev, channel_cfg);
629 }
630 
631 /**
632  * @brief Configure an ADC channel from a struct adc_dt_spec.
633  *
634  * @param spec ADC specification from Devicetree.
635  *
636  * @return A value from adc_channel_setup() or -ENOTSUP if information from
637  * Devicetree is not valid.
638  * @see adc_channel_setup()
639  */
adc_channel_setup_dt(const struct adc_dt_spec * spec)640 static inline int adc_channel_setup_dt(const struct adc_dt_spec *spec)
641 {
642 	if (!spec->channel_cfg_dt_node_exists) {
643 		return -ENOTSUP;
644 	}
645 
646 	return adc_channel_setup(spec->dev, &spec->channel_cfg);
647 }
648 
649 /**
650  * @brief Set a read request.
651  *
652  * @param dev       Pointer to the device structure for the driver instance.
653  * @param sequence  Structure specifying requested sequence of samplings.
654  *
655  * If invoked from user mode, any sequence struct options for callback must
656  * be NULL.
657  *
658  * @retval 0        On success.
659  * @retval -EINVAL  If a parameter with an invalid value has been provided.
660  * @retval -ENOMEM  If the provided buffer is to small to hold the results
661  *                  of all requested samplings.
662  * @retval -ENOTSUP If the requested mode of operation is not supported.
663  * @retval -EBUSY   If another sampling was triggered while the previous one
664  *                  was still in progress. This may occur only when samplings
665  *                  are done with intervals, and it indicates that the selected
666  *                  interval was too small. All requested samples are written
667  *                  in the buffer, but at least some of them were taken with
668  *                  an extra delay compared to what was scheduled.
669  */
670 __syscall int adc_read(const struct device *dev,
671 		       const struct adc_sequence *sequence);
672 
z_impl_adc_read(const struct device * dev,const struct adc_sequence * sequence)673 static inline int z_impl_adc_read(const struct device *dev,
674 				  const struct adc_sequence *sequence)
675 {
676 	const struct adc_driver_api *api =
677 				(const struct adc_driver_api *)dev->api;
678 
679 	return api->read(dev, sequence);
680 }
681 
682 /**
683  * @brief Set an asynchronous read request.
684  *
685  * @note This function is available only if @kconfig{CONFIG_ADC_ASYNC}
686  * is selected.
687  *
688  * If invoked from user mode, any sequence struct options for callback must
689  * be NULL.
690  *
691  * @param dev       Pointer to the device structure for the driver instance.
692  * @param sequence  Structure specifying requested sequence of samplings.
693  * @param async     Pointer to a valid and ready to be signaled struct
694  *                  k_poll_signal. (Note: if NULL this function will not notify
695  *                  the end of the transaction, and whether it went successfully
696  *                  or not).
697  *
698  * @returns 0 on success, negative error code otherwise.
699  *          See adc_read() for a list of possible error codes.
700  *
701  */
702 __syscall int adc_read_async(const struct device *dev,
703 			     const struct adc_sequence *sequence,
704 			     struct k_poll_signal *async);
705 
706 
707 #ifdef CONFIG_ADC_ASYNC
z_impl_adc_read_async(const struct device * dev,const struct adc_sequence * sequence,struct k_poll_signal * async)708 static inline int z_impl_adc_read_async(const struct device *dev,
709 					const struct adc_sequence *sequence,
710 					struct k_poll_signal *async)
711 {
712 	const struct adc_driver_api *api =
713 				(const struct adc_driver_api *)dev->api;
714 
715 	return api->read_async(dev, sequence, async);
716 }
717 #endif /* CONFIG_ADC_ASYNC */
718 
719 /**
720  * @brief Get the internal reference voltage.
721  *
722  * Returns the voltage corresponding to @ref ADC_REF_INTERNAL,
723  * measured in millivolts.
724  *
725  * @return a positive value is the reference voltage value.  Returns
726  * zero if reference voltage information is not available.
727  */
adc_ref_internal(const struct device * dev)728 static inline uint16_t adc_ref_internal(const struct device *dev)
729 {
730 	const struct adc_driver_api *api =
731 				(const struct adc_driver_api *)dev->api;
732 
733 	return api->ref_internal;
734 }
735 
736 /**
737  * @brief Convert a raw ADC value to millivolts.
738  *
739  * This function performs the necessary conversion to transform a raw
740  * ADC measurement to a voltage in millivolts.
741  *
742  * @param ref_mv the reference voltage used for the measurement, in
743  * millivolts.  This may be from adc_ref_internal() or a known
744  * external reference.
745  *
746  * @param gain the ADC gain configuration used to sample the input
747  *
748  * @param resolution the number of bits in the absolute value of the
749  * sample.  For differential sampling this needs to be one less than the
750  * resolution in struct adc_sequence.
751  *
752  * @param valp pointer to the raw measurement value on input, and the
753  * corresponding millivolt value on successful conversion.  If
754  * conversion fails the stored value is left unchanged.
755  *
756  * @retval 0 on successful conversion
757  * @retval -EINVAL if the gain is not reversible
758  */
adc_raw_to_millivolts(int32_t ref_mv,enum adc_gain gain,uint8_t resolution,int32_t * valp)759 static inline int adc_raw_to_millivolts(int32_t ref_mv,
760 					enum adc_gain gain,
761 					uint8_t resolution,
762 					int32_t *valp)
763 {
764 	int32_t adc_mv = *valp * ref_mv;
765 	int ret = adc_gain_invert(gain, &adc_mv);
766 
767 	if (ret == 0) {
768 		*valp = (adc_mv >> resolution);
769 	}
770 
771 	return ret;
772 }
773 
774 /**
775  * @brief Convert a raw ADC value to millivolts using information stored
776  * in a struct adc_dt_spec.
777  *
778  * @param[in] spec ADC specification from Devicetree.
779  * @param[in,out] valp Pointer to the raw measurement value on input, and the
780  * corresponding millivolt value on successful conversion. If conversion fails
781  * the stored value is left unchanged.
782  *
783  * @return A value from adc_raw_to_millivolts() or -ENOTSUP if information from
784  * Devicetree is not valid.
785  * @see adc_raw_to_millivolts()
786  */
adc_raw_to_millivolts_dt(const struct adc_dt_spec * spec,int32_t * valp)787 static inline int adc_raw_to_millivolts_dt(const struct adc_dt_spec *spec,
788 					   int32_t *valp)
789 {
790 	int32_t vref_mv;
791 	uint8_t resolution;
792 
793 	if (!spec->channel_cfg_dt_node_exists) {
794 		return -ENOTSUP;
795 	}
796 
797 	if (spec->channel_cfg.reference == ADC_REF_INTERNAL) {
798 		vref_mv = (int32_t)adc_ref_internal(spec->dev);
799 	} else {
800 		vref_mv = spec->vref_mv;
801 	}
802 
803 	resolution = spec->resolution;
804 
805 	/*
806 	 * For differential channels, one bit less needs to be specified
807 	 * for resolution to achieve correct conversion.
808 	 */
809 	if (spec->channel_cfg.differential) {
810 		resolution -= 1U;
811 	}
812 
813 	return adc_raw_to_millivolts(vref_mv, spec->channel_cfg.gain,
814 				     resolution, valp);
815 }
816 
817 /**
818  * @brief Initialize a struct adc_sequence from information stored in
819  * struct adc_dt_spec.
820  *
821  * Note that this function only initializes the following fields:
822  *
823  * - @ref adc_sequence.channels
824  * - @ref adc_sequence.resolution
825  * - @ref adc_sequence.oversampling
826  *
827  * Other fields should be initialized by the caller.
828  *
829  * @param[in] spec ADC specification from Devicetree.
830  * @param[out] seq Sequence to initialize.
831  *
832  * @retval 0 On success
833  * @retval -ENOTSUP If @p spec does not have valid channel configuration
834  */
adc_sequence_init_dt(const struct adc_dt_spec * spec,struct adc_sequence * seq)835 static inline int adc_sequence_init_dt(const struct adc_dt_spec *spec,
836 				       struct adc_sequence *seq)
837 {
838 	if (!spec->channel_cfg_dt_node_exists) {
839 		return -ENOTSUP;
840 	}
841 
842 	seq->channels = BIT(spec->channel_id);
843 	seq->resolution = spec->resolution;
844 	seq->oversampling = spec->oversampling;
845 
846 	return 0;
847 }
848 
849 /**
850  * @}
851  */
852 
853 #ifdef __cplusplus
854 }
855 #endif
856 
857 #include <syscalls/adc.h>
858 
859 #endif  /* ZEPHYR_INCLUDE_DRIVERS_ADC_H_ */
860