LCOV - code coverage report
Current view: top level - zephyr/drivers - adc.h Coverage Total Hit
Test: new.info Lines: 74.5 % 102 76
Test Date: 2025-09-25 19:22:35

            Line data    Source code
       1            1 : /*
       2              :  * Copyright (c) 2018 Nordic Semiconductor ASA
       3              :  * Copyright (c) 2015 Intel Corporation
       4              :  *
       5              :  * SPDX-License-Identifier: Apache-2.0
       6              :  */
       7              : 
       8              : /**
       9              :  * @file
      10              :  * @ingroup adc_interface
      11              :  * @brief Main header file for ADC (Analog-to-Digital Converter) driver API.
      12              :  */
      13              : 
      14              : #ifndef ZEPHYR_INCLUDE_DRIVERS_ADC_H_
      15              : #define ZEPHYR_INCLUDE_DRIVERS_ADC_H_
      16              : 
      17              : #include <zephyr/device.h>
      18              : #include <zephyr/dt-bindings/adc/adc.h>
      19              : #include <zephyr/kernel.h>
      20              : #include <zephyr/rtio/rtio.h>
      21              : #include <zephyr/dsp/types.h>
      22              : 
      23              : #ifdef __cplusplus
      24              : extern "C" {
      25              : #endif
      26              : 
      27              : /**
      28              :  * @brief Interfaces for Analog-to-Digital Converters (ADC).
      29              :  * @defgroup adc_interface ADC
      30              :  * @since 1.0
      31              :  * @version 1.0.0
      32              :  * @ingroup io_interfaces
      33              :  * @{
      34              :  */
      35              : 
      36              : /** @brief ADC channel gain factors. */
      37            1 : enum adc_gain {
      38              :         ADC_GAIN_1_6, /**< x 1/6. */
      39              :         ADC_GAIN_1_5, /**< x 1/5. */
      40              :         ADC_GAIN_1_4, /**< x 1/4. */
      41              :         ADC_GAIN_2_7, /**< x 2/7. */
      42              :         ADC_GAIN_1_3, /**< x 1/3. */
      43              :         ADC_GAIN_2_5, /**< x 2/5. */
      44              :         ADC_GAIN_1_2, /**< x 1/2. */
      45              :         ADC_GAIN_2_3, /**< x 2/3. */
      46              :         ADC_GAIN_4_5, /**< x 4/5. */
      47              :         ADC_GAIN_1,   /**< x 1. */
      48              :         ADC_GAIN_2,   /**< x 2. */
      49              :         ADC_GAIN_3,   /**< x 3. */
      50              :         ADC_GAIN_4,   /**< x 4. */
      51              :         ADC_GAIN_6,   /**< x 6. */
      52              :         ADC_GAIN_8,   /**< x 8. */
      53              :         ADC_GAIN_12,  /**< x 12. */
      54              :         ADC_GAIN_16,  /**< x 16. */
      55              :         ADC_GAIN_24,  /**< x 24. */
      56              :         ADC_GAIN_32,  /**< x 32. */
      57              :         ADC_GAIN_64,  /**< x 64. */
      58              :         ADC_GAIN_128, /**< x 128. */
      59              : };
      60              : 
      61              : /**
      62              :  * @brief Invert the application of gain to a measurement value.
      63              :  *
      64              :  * For example, if the gain passed in is ADC_GAIN_1_6 and the
      65              :  * referenced value is 10, the value after the function returns is 60.
      66              :  *
      67              :  * @param gain the gain used to amplify the input signal.
      68              :  *
      69              :  * @param value a pointer to a value that initially has the effect of
      70              :  * the applied gain but has that effect removed when this function
      71              :  * successfully returns.  If the gain cannot be reversed the value
      72              :  * remains unchanged.
      73              :  *
      74              :  * @retval 0 if the gain was successfully reversed
      75              :  * @retval -EINVAL if the gain could not be interpreted
      76              :  */
      77            1 : int adc_gain_invert(enum adc_gain gain, int32_t *value);
      78              : 
      79              : /**
      80              :  * @brief Invert the application of gain to a measurement value.
      81              :  *
      82              :  * For example, if the gain passed in is ADC_GAIN_1_6 and the
      83              :  * referenced value is 10, the value after the function returns is 60.
      84              :  *
      85              :  * @param gain the gain used to amplify the input signal.
      86              :  *
      87              :  * @param value a pointer to a value that initially has the effect of
      88              :  * the applied gain but has that effect removed when this function
      89              :  * successfully returns.  If the gain cannot be reversed the value
      90              :  * remains unchanged.
      91              :  *
      92              :  * @retval 0 if the gain was successfully reversed
      93              :  * @retval -EINVAL if the gain could not be interpreted
      94              :  */
      95            1 : int adc_gain_invert_64(enum adc_gain gain, int64_t *value);
      96              : 
      97              : /** @brief ADC references. */
      98            1 : enum adc_reference {
      99              :         ADC_REF_VDD_1,     /**< VDD. */
     100              :         ADC_REF_VDD_1_2,   /**< VDD/2. */
     101              :         ADC_REF_VDD_1_3,   /**< VDD/3. */
     102              :         ADC_REF_VDD_1_4,   /**< VDD/4. */
     103              :         ADC_REF_INTERNAL,  /**< Internal. */
     104              :         ADC_REF_EXTERNAL0, /**< External, input 0. */
     105              :         ADC_REF_EXTERNAL1, /**< External, input 1. */
     106              : };
     107              : 
     108              : /**
     109              :  * @brief Structure for specifying the configuration of an ADC channel.
     110              :  */
     111            1 : struct adc_channel_cfg {
     112              :         /** Gain selection. */
     113            1 :         enum adc_gain gain;
     114              : 
     115              :         /** Reference selection. */
     116            1 :         enum adc_reference reference;
     117              : 
     118              :         /**
     119              :          * Acquisition time.
     120              :          * Use the ADC_ACQ_TIME macro to compose the value for this field or
     121              :          * pass ADC_ACQ_TIME_DEFAULT to use the default setting for a given
     122              :          * hardware (e.g. when the hardware does not allow to configure the
     123              :          * acquisition time).
     124              :          * Particular drivers do not necessarily support all the possible units.
     125              :          * Value range is 0-16383 for a given unit.
     126              :          */
     127            1 :         uint16_t acquisition_time;
     128              : 
     129              :         /**
     130              :          * Channel identifier.
     131              :          * This value primarily identifies the channel within the ADC API - when
     132              :          * a read request is done, the corresponding bit in the "channels" field
     133              :          * of the "adc_sequence" structure must be set to include this channel
     134              :          * in the sampling.
     135              :          * For hardware that does not allow selection of analog inputs for given
     136              :          * channels, but rather have dedicated ones, this value also selects the
     137              :          * physical ADC input to be used in the sampling. Otherwise, when it is
     138              :          * needed to explicitly select an analog input for the channel, or two
     139              :          * inputs when the channel is a differential one, the selection is done
     140              :          * in "input_positive" and "input_negative" fields.
     141              :          * Particular drivers indicate which one of the above two cases they
     142              :          * support by selecting or not a special hidden Kconfig option named
     143              :          * ADC_CONFIGURABLE_INPUTS. If this option is not selected, the macro
     144              :          * CONFIG_ADC_CONFIGURABLE_INPUTS is not defined and consequently the
     145              :          * mentioned two fields are not present in this structure.
     146              :          * While this API allows identifiers from range 0-31, particular drivers
     147              :          * may support only a limited number of channel identifiers (dependent
     148              :          * on the underlying hardware capabilities or configured via a dedicated
     149              :          * Kconfig option).
     150              :          */
     151            1 :         uint8_t channel_id   : 5;
     152              : 
     153              :         /** Channel type: single-ended or differential. */
     154            1 :         uint8_t differential : 1;
     155              : 
     156              : #ifdef CONFIG_ADC_CONFIGURABLE_INPUTS
     157              :         /**
     158              :          * Positive ADC input.
     159              :          * This is a driver dependent value that identifies an ADC input to be
     160              :          * associated with the channel.
     161              :          */
     162              :         uint8_t input_positive;
     163              : 
     164              :         /**
     165              :          * Negative ADC input (used only for differential channels).
     166              :          * This is a driver dependent value that identifies an ADC input to be
     167              :          * associated with the channel.
     168              :          */
     169              :         uint8_t input_negative;
     170              : #endif /* CONFIG_ADC_CONFIGURABLE_INPUTS */
     171              : 
     172              : #ifdef CONFIG_ADC_CONFIGURABLE_EXCITATION_CURRENT_SOURCE_PIN
     173              :         uint8_t current_source_pin_set : 1;
     174              :         /**
     175              :          * Output pin for the current sources.
     176              :          * This is only available if the driver enables this feature
     177              :          * via the hidden configuration option ADC_CONFIGURABLE_EXCITATION_CURRENT_SOURCE_PIN.
     178              :          * The meaning itself is then defined by the driver itself.
     179              :          */
     180              :         uint8_t current_source_pin[2];
     181              : #endif /* CONFIG_ADC_CONFIGURABLE_EXCITATION_CURRENT_SOURCE_PIN */
     182              : 
     183              : #ifdef CONFIG_ADC_CONFIGURABLE_VBIAS_PIN
     184              :         /**
     185              :          * Output pins for the bias voltage.
     186              :          * This is only available if the driver enables this feature
     187              :          * via the hidden configuration option ADC_CONFIGURABLE_VBIAS_PIN.
     188              :          * The field is interpreted as a bitmask, where each bit represents
     189              :          * one of the input pins. The actual mapping to the physical pins
     190              :          * depends on the driver itself.
     191              :          */
     192              :         uint32_t vbias_pins;
     193              : #endif /* CONFIG_ADC_CONFIGURABLE_VBIAS_PIN */
     194              : };
     195              : 
     196              : /**
     197              :  * @brief Get ADC channel configuration from a given devicetree node.
     198              :  *
     199              :  * This returns a static initializer for a <tt>struct adc_channel_cfg</tt>
     200              :  * filled with data from a given devicetree node.
     201              :  *
     202              :  * Example devicetree fragment:
     203              :  *
     204              :  * @code{.dts}
     205              :  * &adc {
     206              :  *    #address-cells = <1>;
     207              :  *    #size-cells = <0>;
     208              :  *
     209              :  *    channel@0 {
     210              :  *        reg = <0>;
     211              :  *        zephyr,gain = "ADC_GAIN_1_6";
     212              :  *        zephyr,reference = "ADC_REF_INTERNAL";
     213              :  *        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 20)>;
     214              :  *        zephyr,input-positive = <NRF_SAADC_AIN6>;
     215              :  *        zephyr,input-negative = <NRF_SAADC_AIN7>;
     216              :  *    };
     217              :  *
     218              :  *    channel@1 {
     219              :  *        reg = <1>;
     220              :  *        zephyr,gain = "ADC_GAIN_1_6";
     221              :  *        zephyr,reference = "ADC_REF_INTERNAL";
     222              :  *        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
     223              :  *        zephyr,input-positive = <NRF_SAADC_AIN0>;
     224              :  *    };
     225              :  * };
     226              :  * @endcode
     227              :  *
     228              :  * Example usage:
     229              :  *
     230              :  * @code{.c}
     231              :  * static const struct adc_channel_cfg ch0_cfg_dt =
     232              :  *     ADC_CHANNEL_CFG_DT(DT_CHILD(DT_NODELABEL(adc), channel_0));
     233              :  * static const struct adc_channel_cfg ch1_cfg_dt =
     234              :  *     ADC_CHANNEL_CFG_DT(DT_CHILD(DT_NODELABEL(adc), channel_1));
     235              :  *
     236              :  * // Initializes 'ch0_cfg_dt' to:
     237              :  * // {
     238              :  * //     .channel_id = 0,
     239              :  * //     .gain = ADC_GAIN_1_6,
     240              :  * //     .reference = ADC_REF_INTERNAL,
     241              :  * //     .acquisition_time = ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 20),
     242              :  * //     .differential = true,
     243              :  * //     .input_positive = NRF_SAADC_AIN6,
     244              :  * //     .input-negative = NRF_SAADC_AIN7,
     245              :  * // }
     246              :  * // and 'ch1_cfg_dt' to:
     247              :  * // {
     248              :  * //     .channel_id = 1,
     249              :  * //     .gain = ADC_GAIN_1_6,
     250              :  * //     .reference = ADC_REF_INTERNAL,
     251              :  * //     .acquisition_time = ADC_ACQ_TIME_DEFAULT,
     252              :  * //     .input_positive = NRF_SAADC_AIN0,
     253              :  * // }
     254              :  * @endcode
     255              :  *
     256              :  * @param node_id Devicetree node identifier.
     257              :  *
     258              :  * @return Static initializer for an adc_channel_cfg structure.
     259              :  */
     260            1 : #define ADC_CHANNEL_CFG_DT(node_id) { \
     261              :         .gain             = DT_STRING_TOKEN(node_id, zephyr_gain), \
     262              :         .reference        = DT_STRING_TOKEN(node_id, zephyr_reference), \
     263              :         .acquisition_time = DT_PROP(node_id, zephyr_acquisition_time), \
     264              :         .channel_id       = DT_REG_ADDR(node_id), \
     265              : COND_CODE_1(UTIL_OR(DT_PROP(node_id, zephyr_differential), \
     266              :                    UTIL_AND(CONFIG_ADC_CONFIGURABLE_INPUTS, \
     267              :                             DT_NODE_HAS_PROP(node_id, zephyr_input_negative))), \
     268              :         (.differential    = true,), \
     269              :         (.differential    = false,)) \
     270              : IF_ENABLED(CONFIG_ADC_CONFIGURABLE_INPUTS, \
     271              :         (.input_positive  = DT_PROP_OR(node_id, zephyr_input_positive, 0), \
     272              :          .input_negative  = DT_PROP_OR(node_id, zephyr_input_negative, 0),)) \
     273              : IF_ENABLED(CONFIG_ADC_CONFIGURABLE_EXCITATION_CURRENT_SOURCE_PIN, \
     274              :         (.current_source_pin_set = DT_NODE_HAS_PROP(node_id, zephyr_current_source_pin), \
     275              :          .current_source_pin = DT_PROP_OR(node_id, zephyr_current_source_pin, {0}),)) \
     276              : IF_ENABLED(CONFIG_ADC_CONFIGURABLE_VBIAS_PIN, \
     277              :         (.vbias_pins = DT_PROP_OR(node_id, zephyr_vbias_pins, 0),)) \
     278              : }
     279              : 
     280              : /**
     281              :  * @brief Container for ADC channel information specified in devicetree.
     282              :  *
     283              :  * @see ADC_DT_SPEC_GET_BY_IDX
     284              :  * @see ADC_DT_SPEC_GET
     285              :  */
     286            1 : struct adc_dt_spec {
     287              :         /**
     288              :          * Pointer to the device structure for the ADC driver instance
     289              :          * used by this io-channel.
     290              :          */
     291            1 :         const struct device *dev;
     292              : 
     293              :         /** ADC channel identifier used by this io-channel. */
     294            1 :         uint8_t channel_id;
     295              : 
     296              :         /**
     297              :          * Flag indicating whether configuration of the associated ADC channel
     298              :          * is provided as a child node of the corresponding ADC controller in
     299              :          * devicetree.
     300              :          */
     301            1 :         bool channel_cfg_dt_node_exists;
     302              : 
     303              :         /**
     304              :          * Configuration of the associated ADC channel specified in devicetree.
     305              :          * This field is valid only when @a channel_cfg_dt_node_exists is set
     306              :          * to @a true.
     307              :          */
     308            1 :         struct adc_channel_cfg channel_cfg;
     309              : 
     310              :         /**
     311              :          * Voltage of the reference selected for the channel or 0 if this
     312              :          * value is not provided in devicetree.
     313              :          * This field is valid only when @a channel_cfg_dt_node_exists is set
     314              :          * to @a true.
     315              :          */
     316            1 :         uint16_t vref_mv;
     317              : 
     318              :         /**
     319              :          * ADC resolution to be used for that channel.
     320              :          * This field is valid only when @a channel_cfg_dt_node_exists is set
     321              :          * to @a true.
     322              :          */
     323            1 :         uint8_t resolution;
     324              : 
     325              :         /**
     326              :          * Oversampling setting to be used for that channel.
     327              :          * This field is valid only when @a channel_cfg_dt_node_exists is set
     328              :          * to @a true.
     329              :          */
     330            1 :         uint8_t oversampling;
     331              : };
     332              : 
     333              : /** @cond INTERNAL_HIDDEN */
     334              : 
     335              : #define ADC_DT_SPEC_STRUCT(ctlr, input) { \
     336              :                 .dev = DEVICE_DT_GET(ctlr), \
     337              :                 .channel_id = input, \
     338              :                 ADC_CHANNEL_CFG_FROM_DT_NODE(\
     339              :                         ADC_CHANNEL_DT_NODE(ctlr, input)) \
     340              :         }
     341              : 
     342              : #define ADC_CHANNEL_DT_NODE(ctlr, input) \
     343              :         DT_FOREACH_CHILD_VARGS(ctlr, ADC_FOREACH_INPUT, input)
     344              : 
     345              : #define ADC_FOREACH_INPUT(node, input) \
     346              :         IF_ENABLED(IS_EQ(DT_REG_ADDR_RAW(node), input), (node))
     347              : 
     348              : #define ADC_CHANNEL_CFG_FROM_DT_NODE(node_id) \
     349              :         IF_ENABLED(DT_NODE_EXISTS(node_id), \
     350              :                 (.channel_cfg_dt_node_exists = true, \
     351              :                  .channel_cfg  = ADC_CHANNEL_CFG_DT(node_id), \
     352              :                  .vref_mv      = DT_PROP_OR(node_id, zephyr_vref_mv, 0), \
     353              :                  .resolution   = DT_PROP_OR(node_id, zephyr_resolution, 0), \
     354              :                  .oversampling = DT_PROP_OR(node_id, zephyr_oversampling, 0),))
     355              : 
     356              : /** @endcond */
     357              : 
     358              : /**
     359              :  * @brief Get ADC io-channel information from devicetree by name.
     360              :  *
     361              :  * This returns a static initializer for an @p adc_dt_spec structure
     362              :  * given a devicetree node and a channel name. The node must have
     363              :  * the "io-channels" property defined.
     364              :  *
     365              :  * Example devicetree fragment:
     366              :  *
     367              :  * @code{.dts}
     368              :  * / {
     369              :  *     zephyr,user {
     370              :  *         io-channels = <&adc0 1>, <&adc0 3>;
     371              :  *         io-channel-names = "A0", "A1";
     372              :  *     };
     373              :  * };
     374              :  *
     375              :  * &adc0 {
     376              :  *    #address-cells = <1>;
     377              :  *    #size-cells = <0>;
     378              :  *
     379              :  *    channel@3 {
     380              :  *        reg = <3>;
     381              :  *        zephyr,gain = "ADC_GAIN_1_5";
     382              :  *        zephyr,reference = "ADC_REF_VDD_1_4";
     383              :  *        zephyr,vref-mv = <750>;
     384              :  *        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
     385              :  *        zephyr,resolution = <12>;
     386              :  *        zephyr,oversampling = <4>;
     387              :  *    };
     388              :  * };
     389              :  * @endcode
     390              :  *
     391              :  * Example usage:
     392              :  *
     393              :  * @code{.c}
     394              :  * static const struct adc_dt_spec adc_chan0 =
     395              :  *     ADC_DT_SPEC_GET_BY_NAME(DT_PATH(zephyr_user), a0);
     396              :  * static const struct adc_dt_spec adc_chan1 =
     397              :  *     ADC_DT_SPEC_GET_BY_NAME(DT_PATH(zephyr_user), a1);
     398              :  *
     399              :  * // Initializes 'adc_chan0' to:
     400              :  * // {
     401              :  * //     .dev = DEVICE_DT_GET(DT_NODELABEL(adc0)),
     402              :  * //     .channel_id = 1,
     403              :  * // }
     404              :  * // and 'adc_chan1' to:
     405              :  * // {
     406              :  * //     .dev = DEVICE_DT_GET(DT_NODELABEL(adc0)),
     407              :  * //     .channel_id = 3,
     408              :  * //     .channel_cfg_dt_node_exists = true,
     409              :  * //     .channel_cfg = {
     410              :  * //         .channel_id = 3,
     411              :  * //         .gain = ADC_GAIN_1_5,
     412              :  * //         .reference = ADC_REF_VDD_1_4,
     413              :  * //         .acquisition_time = ADC_ACQ_TIME_DEFAULT,
     414              :  * //     },
     415              :  * //     .vref_mv = 750,
     416              :  * //     .resolution = 12,
     417              :  * //     .oversampling = 4,
     418              :  * // }
     419              :  * @endcode
     420              :  *
     421              :  * @param node_id Devicetree node identifier.
     422              :  * @param name Channel name.
     423              :  *
     424              :  * @return Static initializer for an adc_dt_spec structure.
     425              :  */
     426            1 : #define ADC_DT_SPEC_GET_BY_NAME(node_id, name) \
     427              :         ADC_DT_SPEC_STRUCT(DT_IO_CHANNELS_CTLR_BY_NAME(node_id, name), \
     428              :                            DT_IO_CHANNELS_INPUT_BY_NAME(node_id, name))
     429              : 
     430              : /** @brief Get ADC io-channel information from a DT_DRV_COMPAT devicetree
     431              :  *         instance by name.
     432              :  *
     433              :  * @see ADC_DT_SPEC_GET_BY_NAME()
     434              :  *
     435              :  * @param inst DT_DRV_COMPAT instance number
     436              :  * @param name Channel name.
     437              :  *
     438              :  * @return Static initializer for an adc_dt_spec structure.
     439              :  */
     440            1 : #define ADC_DT_SPEC_INST_GET_BY_NAME(inst, name) \
     441              :         ADC_DT_SPEC_GET_BY_NAME(DT_DRV_INST(inst), name)
     442              : 
     443              : /**
     444              :  * @brief Get ADC io-channel information from devicetree.
     445              :  *
     446              :  * This returns a static initializer for an @p adc_dt_spec structure
     447              :  * given a devicetree node and a channel index. The node must have
     448              :  * the "io-channels" property defined.
     449              :  *
     450              :  * Example devicetree fragment:
     451              :  *
     452              :  * @code{.dts}
     453              :  * / {
     454              :  *     zephyr,user {
     455              :  *         io-channels = <&adc0 1>, <&adc0 3>;
     456              :  *     };
     457              :  * };
     458              :  *
     459              :  * &adc0 {
     460              :  *    #address-cells = <1>;
     461              :  *    #size-cells = <0>;
     462              :  *
     463              :  *    channel@3 {
     464              :  *        reg = <3>;
     465              :  *        zephyr,gain = "ADC_GAIN_1_5";
     466              :  *        zephyr,reference = "ADC_REF_VDD_1_4";
     467              :  *        zephyr,vref-mv = <750>;
     468              :  *        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
     469              :  *        zephyr,resolution = <12>;
     470              :  *        zephyr,oversampling = <4>;
     471              :  *    };
     472              :  * };
     473              :  * @endcode
     474              :  *
     475              :  * Example usage:
     476              :  *
     477              :  * @code{.c}
     478              :  * static const struct adc_dt_spec adc_chan0 =
     479              :  *     ADC_DT_SPEC_GET_BY_IDX(DT_PATH(zephyr_user), 0);
     480              :  * static const struct adc_dt_spec adc_chan1 =
     481              :  *     ADC_DT_SPEC_GET_BY_IDX(DT_PATH(zephyr_user), 1);
     482              :  *
     483              :  * // Initializes 'adc_chan0' to:
     484              :  * // {
     485              :  * //     .dev = DEVICE_DT_GET(DT_NODELABEL(adc0)),
     486              :  * //     .channel_id = 1,
     487              :  * // }
     488              :  * // and 'adc_chan1' to:
     489              :  * // {
     490              :  * //     .dev = DEVICE_DT_GET(DT_NODELABEL(adc0)),
     491              :  * //     .channel_id = 3,
     492              :  * //     .channel_cfg_dt_node_exists = true,
     493              :  * //     .channel_cfg = {
     494              :  * //         .channel_id = 3,
     495              :  * //         .gain = ADC_GAIN_1_5,
     496              :  * //         .reference = ADC_REF_VDD_1_4,
     497              :  * //         .acquisition_time = ADC_ACQ_TIME_DEFAULT,
     498              :  * //     },
     499              :  * //     .vref_mv = 750,
     500              :  * //     .resolution = 12,
     501              :  * //     .oversampling = 4,
     502              :  * // }
     503              :  * @endcode
     504              :  *
     505              :  * @see ADC_DT_SPEC_GET()
     506              :  *
     507              :  * @param node_id Devicetree node identifier.
     508              :  * @param idx Channel index.
     509              :  *
     510              :  * @return Static initializer for an adc_dt_spec structure.
     511              :  */
     512            1 : #define ADC_DT_SPEC_GET_BY_IDX(node_id, idx) \
     513              :         ADC_DT_SPEC_STRUCT(DT_IO_CHANNELS_CTLR_BY_IDX(node_id, idx), \
     514              :                            DT_IO_CHANNELS_INPUT_BY_IDX(node_id, idx))
     515              : 
     516              : /** @brief Get ADC io-channel information from a DT_DRV_COMPAT devicetree
     517              :  *         instance.
     518              :  *
     519              :  * @see ADC_DT_SPEC_GET_BY_IDX()
     520              :  *
     521              :  * @param inst DT_DRV_COMPAT instance number
     522              :  * @param idx Channel index.
     523              :  *
     524              :  * @return Static initializer for an adc_dt_spec structure.
     525              :  */
     526            1 : #define ADC_DT_SPEC_INST_GET_BY_IDX(inst, idx) \
     527              :         ADC_DT_SPEC_GET_BY_IDX(DT_DRV_INST(inst), idx)
     528              : 
     529              : /**
     530              :  * @brief Equivalent to ADC_DT_SPEC_GET_BY_IDX(node_id, 0).
     531              :  *
     532              :  * @see ADC_DT_SPEC_GET_BY_IDX()
     533              :  *
     534              :  * @param node_id Devicetree node identifier.
     535              :  *
     536              :  * @return Static initializer for an adc_dt_spec structure.
     537              :  */
     538            1 : #define ADC_DT_SPEC_GET(node_id) ADC_DT_SPEC_GET_BY_IDX(node_id, 0)
     539              : 
     540              : /** @brief Equivalent to ADC_DT_SPEC_INST_GET_BY_IDX(inst, 0).
     541              :  *
     542              :  * @see ADC_DT_SPEC_GET()
     543              :  *
     544              :  * @param inst DT_DRV_COMPAT instance number
     545              :  *
     546              :  * @return Static initializer for an adc_dt_spec structure.
     547              :  */
     548            1 : #define ADC_DT_SPEC_INST_GET(inst) ADC_DT_SPEC_GET(DT_DRV_INST(inst))
     549              : 
     550              : /* Forward declaration of the adc_sequence structure. */
     551              : struct adc_sequence;
     552              : 
     553              : /**
     554              :  * @brief Action to be performed after a sampling is done.
     555              :  */
     556            1 : enum adc_action {
     557              :         /** The sequence should be continued normally. */
     558              :         ADC_ACTION_CONTINUE = 0,
     559              : 
     560              :         /**
     561              :          * The sampling should be repeated. New samples or sample should be
     562              :          * read from the ADC and written in the same place as the recent ones.
     563              :          */
     564              :         ADC_ACTION_REPEAT,
     565              : 
     566              :         /** The sequence should be finished immediately. */
     567              :         ADC_ACTION_FINISH,
     568              : };
     569              : 
     570              : /**
     571              :  * @brief Type definition of the optional callback function to be called after
     572              :  *        a requested sampling is done.
     573              :  *
     574              :  * @param dev             Pointer to the device structure for the driver
     575              :  *                        instance.
     576              :  * @param sequence        Pointer to the sequence structure that triggered
     577              :  *                        the sampling. This parameter points to a copy of
     578              :  *                        the structure that was supplied to the call that
     579              :  *                        started the sampling sequence, thus it cannot be
     580              :  *                        used with the CONTAINER_OF() macro to retrieve
     581              :  *                        some other data associated with the sequence.
     582              :  *                        Instead, the adc_sequence_options::user_data field
     583              :  *                        should be used for such purpose.
     584              :  *
     585              :  * @param sampling_index  Index (0-65535) of the sampling done.
     586              :  *
     587              :  * @returns Action to be performed by the driver. See @ref adc_action.
     588              :  */
     589              : typedef enum adc_action (*adc_sequence_callback)(const struct device *dev,
     590              :                                                  const struct adc_sequence *sequence,
     591              :                                                  uint16_t sampling_index);
     592              : 
     593              : /**
     594              :  * @brief Structure defining additional options for an ADC sampling sequence.
     595              :  */
     596            1 : struct adc_sequence_options {
     597              :         /**
     598              :          * Interval between consecutive samplings (in microseconds), 0 means
     599              :          * sample as fast as possible, without involving any timer.
     600              :          * The accuracy of this interval is dependent on the implementation of
     601              :          * a given driver. The default routine that handles the intervals uses
     602              :          * a kernel timer for this purpose, thus, it has the accuracy of the
     603              :          * kernel's system clock. Particular drivers may use some dedicated
     604              :          * hardware timers and achieve a better precision.
     605              :          */
     606            1 :         uint32_t interval_us;
     607              : 
     608              :         /**
     609              :          * Callback function to be called after each sampling is done.
     610              :          * Optional - set to NULL if it is not needed.
     611              :          */
     612            1 :         adc_sequence_callback callback;
     613              : 
     614              :         /**
     615              :          * Pointer to user data. It can be used to associate the sequence
     616              :          * with any other data that is needed in the callback function.
     617              :          */
     618            1 :         void *user_data;
     619              : 
     620              :         /**
     621              :          * Number of extra samplings to perform (the total number of samplings
     622              :          * is 1 + extra_samplings).
     623              :          */
     624            1 :         uint16_t extra_samplings;
     625              : };
     626              : 
     627              : /**
     628              :  * @brief Structure defining an ADC sampling sequence.
     629              :  */
     630            1 : struct adc_sequence {
     631              :         /**
     632              :          * Pointer to a structure defining additional options for the sequence.
     633              :          * If NULL, the sequence consists of a single sampling.
     634              :          */
     635            1 :         const struct adc_sequence_options *options;
     636              : 
     637              :         /**
     638              :          * Bit-mask indicating the channels to be included in each sampling
     639              :          * of this sequence.
     640              :          * All selected channels must be configured with adc_channel_setup()
     641              :          * before they are used in a sequence.
     642              :          * The least significant bit corresponds to channel 0.
     643              :          */
     644            1 :         uint32_t channels;
     645              : 
     646              :         /**
     647              :          * Pointer to a buffer where the samples are to be written. Samples
     648              :          * from subsequent samplings are written sequentially in the buffer.
     649              :          * The number of samples written for each sampling is determined by
     650              :          * the number of channels selected in the "channels" field.
     651              :          * The values written to the buffer represent a sample from each
     652              :          * selected channel starting from the one with the lowest ID.
     653              :          * The buffer must be of an appropriate size, taking into account
     654              :          * the number of selected channels and the ADC resolution used,
     655              :          * as well as the number of samplings contained in the sequence.
     656              :          */
     657            1 :         void *buffer;
     658              : 
     659              :         /**
     660              :          * Specifies the actual size of the buffer pointed by the "buffer"
     661              :          * field (in bytes). The driver must ensure that samples are not
     662              :          * written beyond the limit and it must return an error if the buffer
     663              :          * turns out to be not large enough to hold all the requested samples.
     664              :          */
     665            1 :         size_t buffer_size;
     666              : 
     667              :         /**
     668              :          * ADC resolution.
     669              :          * For single-ended channels the sample values are from range:
     670              :          *   0 .. 2^resolution - 1,
     671              :          * for differential ones:
     672              :          *   - 2^(resolution-1) .. 2^(resolution-1) - 1.
     673              :          */
     674            1 :         uint8_t resolution;
     675              : 
     676              :         /**
     677              :          * Oversampling setting.
     678              :          * Each sample is averaged from 2^oversampling conversion results.
     679              :          * This feature may be unsupported by a given ADC hardware, or in
     680              :          * a specific mode (e.g. when sampling multiple channels).
     681              :          */
     682            1 :         uint8_t oversampling;
     683              : 
     684              :         /**
     685              :          * Perform calibration before the reading is taken if requested.
     686              :          *
     687              :          * The impact of channel configuration on the calibration
     688              :          * process is specific to the underlying hardware.  ADC
     689              :          * implementations that do not support calibration should
     690              :          * ignore this flag.
     691              :          */
     692            1 :         bool calibrate;
     693              : };
     694              : 
     695            0 : struct adc_data_header {
     696              :         /**
     697              :          * The closest timestamp for when the first frame was generated as attained by
     698              :          * :c:func:`k_uptime_ticks`.
     699              :          */
     700            1 :         uint64_t base_timestamp_ns;
     701              :         /**
     702              :          * The number of elements in the 'readings' array.
     703              :          *
     704              :          * This must be at least 1
     705              :          */
     706            1 :         uint16_t reading_count;
     707              : };
     708              : 
     709              : /**
     710              :  * Data for the adc channel.
     711              :  */
     712            1 : struct adc_data {
     713            0 :         struct adc_data_header header;
     714            0 :         int8_t shift;
     715            0 :         struct adc_sample_data {
     716            0 :                 uint32_t timestamp_delta;
     717              :                 union {
     718            0 :                         q31_t value;
     719            0 :                 };
     720            0 :         } readings[1];
     721              : };
     722              : 
     723              : /**
     724              :  * @brief ADC trigger types.
     725              :  */
     726            1 : enum adc_trigger_type {
     727              :         /** Trigger fires whenever new data is ready. */
     728              :         ADC_TRIG_DATA_READY,
     729              : 
     730              :         /** Trigger fires when the FIFO watermark has been reached. */
     731              :         ADC_TRIG_FIFO_WATERMARK,
     732              : 
     733              :         /** Trigger fires when the FIFO becomes full. */
     734              :         ADC_TRIG_FIFO_FULL,
     735              : 
     736              :         /**
     737              :          * Number of all common adc triggers.
     738              :          */
     739              :         ADC_TRIG_COMMON_COUNT,
     740              : 
     741              :         /**
     742              :          * This and higher values are adc specific.
     743              :          * Refer to the adc header file.
     744              :          */
     745              :         ADC_TRIG_PRIV_START = ADC_TRIG_COMMON_COUNT,
     746              : 
     747              :         /**
     748              :          * Maximum value describing a adc trigger type.
     749              :          */
     750              :         ADC_TRIG_MAX = INT16_MAX,
     751              : };
     752              : 
     753              : /**
     754              :  * @brief Options for what to do with the associated data when a trigger is consumed
     755              :  */
     756            1 : enum adc_stream_data_opt {
     757              :         /** @brief Include whatever data is associated with the trigger */
     758              :         ADC_STREAM_DATA_INCLUDE = 0,
     759              :         /** @brief Do nothing with the associated trigger data, it may be consumed later */
     760              :         ADC_STREAM_DATA_NOP = 1,
     761              :         /** @brief Flush/clear whatever data is associated with the trigger */
     762              :         ADC_STREAM_DATA_DROP = 2,
     763              : };
     764              : 
     765            0 : struct adc_stream_trigger {
     766            0 :         enum adc_trigger_type trigger;
     767            0 :         enum adc_stream_data_opt opt;
     768              : };
     769              : 
     770              : /**
     771              :  * @brief ADC Channel Specification
     772              :  *
     773              :  * A ADC channel specification is a unique identifier per ADC device describing
     774              :  * a measurement channel.
     775              :  *
     776              :  */
     777            1 : struct adc_chan_spec {
     778            1 :         uint8_t chan_idx; /**< A ADC channel index */
     779            1 :         uint8_t chan_resolution;  /**< A ADC channel resolution */
     780              : };
     781              : 
     782              : /*
     783              :  * Internal data structure used to store information about the IODevice for async reading and
     784              :  * streaming adc data.
     785              :  */
     786            0 : struct adc_read_config {
     787            0 :         const struct device *adc;
     788            0 :         const bool is_streaming;
     789            0 :         const struct adc_dt_spec *adc_spec;
     790            0 :         const struct adc_stream_trigger *triggers;
     791            0 :         struct adc_sequence *sequence;
     792            0 :         uint16_t fifo_watermark_lvl;
     793            0 :         uint16_t fifo_mode;
     794            0 :         size_t adc_spec_cnt;
     795            0 :         size_t trigger_cnt;
     796              : };
     797              : 
     798              : /**
     799              :  * @brief Decodes a single raw data buffer
     800              :  *
     801              :  */
     802            1 : struct adc_decoder_api {
     803              :         /**
     804              :          * @brief Get the number of frames in the current buffer.
     805              :          *
     806              :          * @param[in]  buffer The buffer provided on the @ref rtio context.
     807              :          * @param[in]  channel The channel to get the count for
     808              :          * @param[out] frame_count The number of frames on the buffer (at least 1)
     809              :          * @return 0 on success
     810              :          * @return -ENOTSUP if the channel/channel_idx aren't found
     811              :          */
     812            1 :         int (*get_frame_count)(const uint8_t *buffer, uint32_t channel,
     813              :                                uint16_t *frame_count);
     814              : 
     815              :         /**
     816              :          * @brief Get the size required to decode a given channel
     817              :          *
     818              :          * When decoding a single frame, use @p base_size. For every additional frame, add another
     819              :          * @p frame_size. As an example, to decode 3 frames use: 'base_size + 2 * frame_size'.
     820              :          *
     821              :          * @param[in] adc_spec ADC Specs
     822              :          * @param[in]  channel The channel to query
     823              :          * @param[out] base_size The size of decoding the first frame
     824              :          * @param[out] frame_size The additional size of every additional frame
     825              :          * @return 0 on success
     826              :          * @return -ENOTSUP if the channel is not supported
     827              :          */
     828            1 :         int (*get_size_info)(struct adc_dt_spec adc_spec, uint32_t channel, size_t *base_size,
     829              :                              size_t *frame_size);
     830              : 
     831              :         /**
     832              :          * @brief Decode up to @p max_count samples from the buffer
     833              :          *
     834              :          * Decode samples of channel across multiple frames. If there exist
     835              :          * multiple instances of the same channel, @p channel_index is used to differentiate them.
     836              :          *
     837              :          * @param[in]     buffer The buffer provided on the @ref rtio context
     838              :          * @param[in]     channel The channel to decode
     839              :          * @param[in,out] fit The current frame iterator
     840              :          * @param[in]     max_count The maximum number of channels to decode.
     841              :          * @param[out]    data_out The decoded data
     842              :          * @return 0 no more samples to decode
     843              :          * @return >0 the number of decoded frames
     844              :          * @return <0 on error
     845              :          */
     846            1 :         int (*decode)(const uint8_t *buffer, uint32_t channel, uint32_t *fit,
     847              :                       uint16_t max_count, void *data_out);
     848              : 
     849              :         /**
     850              :          * @brief Check if the given trigger type is present
     851              :          *
     852              :          * @param[in] buffer The buffer provided on the @ref rtio context
     853              :          * @param[in] trigger The trigger type in question
     854              :          * @return Whether the trigger is present in the buffer
     855              :          */
     856            1 :         bool (*has_trigger)(const uint8_t *buffer, enum adc_trigger_type trigger);
     857              : };
     858              : 
     859              : /**
     860              :  * @brief Type definition of ADC API function for configuring a channel.
     861              :  * See adc_channel_setup() for argument descriptions.
     862              :  */
     863            1 : typedef int (*adc_api_channel_setup)(const struct device *dev,
     864              :                                      const struct adc_channel_cfg *channel_cfg);
     865              : 
     866              : /**
     867              :  * @brief Type definition of ADC API function for setting a read request.
     868              :  * See adc_read() for argument descriptions.
     869              :  */
     870            1 : typedef int (*adc_api_read)(const struct device *dev,
     871              :                             const struct adc_sequence *sequence);
     872              : 
     873              : /**
     874              :  * @brief Type definition of ADC API function for setting an submit
     875              :  *        stream request.
     876              :  */
     877            1 : typedef void (*adc_api_submit)(const struct device *dev,
     878              :                                   struct rtio_iodev_sqe *sqe);
     879              : 
     880              : /**
     881              :  * @brief Get the decoder associate with the given device
     882              :  *
     883              :  * @see adc_get_decoder() for more details
     884              :  */
     885            1 : typedef int (*adc_api_get_decoder)(const struct device *dev,
     886              :                                     const struct adc_decoder_api **api);
     887              : 
     888              : 
     889              : /**
     890              :  * @brief Type definition of ADC API function for setting an asynchronous
     891              :  *        read request.
     892              :  * See adc_read_async() for argument descriptions.
     893              :  */
     894            1 : typedef int (*adc_api_read_async)(const struct device *dev,
     895              :                                   const struct adc_sequence *sequence,
     896              :                                   struct k_poll_signal *async);
     897              : 
     898              : /**
     899              :  * @brief ADC driver API
     900              :  *
     901              :  * This is the mandatory API any ADC driver needs to expose.
     902              :  */
     903            1 : __subsystem struct adc_driver_api {
     904            0 :         adc_api_channel_setup channel_setup;
     905            0 :         adc_api_read          read;
     906              : #ifdef CONFIG_ADC_ASYNC
     907              :         adc_api_read_async    read_async;
     908              : #endif
     909              : #ifdef CONFIG_ADC_STREAM
     910              :         adc_api_submit    submit;
     911              :         adc_api_get_decoder get_decoder;
     912              : #endif
     913            0 :         uint16_t ref_internal;  /* mV */
     914              : };
     915              : 
     916              : /**
     917              :  * @brief Configure an ADC channel.
     918              :  *
     919              :  * It is required to call this function and configure each channel before it is
     920              :  * selected for a read request.
     921              :  *
     922              :  * @param dev          Pointer to the device structure for the driver instance.
     923              :  * @param channel_cfg  Channel configuration.
     924              :  *
     925              :  * @retval 0       On success.
     926              :  * @retval -EINVAL If a parameter with an invalid value has been provided.
     927              :  */
     928            1 : __syscall int adc_channel_setup(const struct device *dev,
     929              :                                 const struct adc_channel_cfg *channel_cfg);
     930              : 
     931              : static inline int z_impl_adc_channel_setup(const struct device *dev,
     932              :                                            const struct adc_channel_cfg *channel_cfg)
     933              : {
     934              :         return DEVICE_API_GET(adc, dev)->channel_setup(dev, channel_cfg);
     935              : }
     936              : 
     937              : /**
     938              :  * @brief Configure an ADC channel from a struct adc_dt_spec.
     939              :  *
     940              :  * @param spec ADC specification from Devicetree.
     941              :  *
     942              :  * @return A value from adc_channel_setup() or -ENOTSUP if information from
     943              :  * Devicetree is not valid.
     944              :  * @see adc_channel_setup()
     945              :  */
     946            1 : static inline int adc_channel_setup_dt(const struct adc_dt_spec *spec)
     947              : {
     948              :         if (!spec->channel_cfg_dt_node_exists) {
     949              :                 return -ENOTSUP;
     950              :         }
     951              : 
     952              :         return adc_channel_setup(spec->dev, &spec->channel_cfg);
     953              : }
     954              : 
     955              : /**
     956              :  * @brief Set a read request.
     957              :  *
     958              :  * @param dev       Pointer to the device structure for the driver instance.
     959              :  * @param sequence  Structure specifying requested sequence of samplings.
     960              :  *
     961              :  * If invoked from user mode, any sequence struct options for callback must
     962              :  * be NULL.
     963              :  *
     964              :  * @retval 0        On success.
     965              :  * @retval -EINVAL  If a parameter with an invalid value has been provided.
     966              :  * @retval -ENOMEM  If the provided buffer is to small to hold the results
     967              :  *                  of all requested samplings.
     968              :  * @retval -ENOTSUP If the requested mode of operation is not supported.
     969              :  * @retval -EBUSY   If another sampling was triggered while the previous one
     970              :  *                  was still in progress. This may occur only when samplings
     971              :  *                  are done with intervals, and it indicates that the selected
     972              :  *                  interval was too small. All requested samples are written
     973              :  *                  in the buffer, but at least some of them were taken with
     974              :  *                  an extra delay compared to what was scheduled.
     975              :  */
     976            1 : __syscall int adc_read(const struct device *dev,
     977              :                        const struct adc_sequence *sequence);
     978              : 
     979              : static inline int z_impl_adc_read(const struct device *dev,
     980              :                                   const struct adc_sequence *sequence)
     981              : {
     982              :         return DEVICE_API_GET(adc, dev)->read(dev, sequence);
     983              : }
     984              : 
     985              : /**
     986              :  * @brief Set a read request from a struct adc_dt_spec.
     987              :  *
     988              :  * @param spec ADC specification from Devicetree.
     989              :  * @param sequence  Structure specifying requested sequence of samplings.
     990              :  *
     991              :  * @return A value from adc_read().
     992              :  * @see adc_read()
     993              :  */
     994            1 : static inline int adc_read_dt(const struct adc_dt_spec *spec,
     995              :                               const struct adc_sequence *sequence)
     996              : {
     997              :         return adc_read(spec->dev, sequence);
     998              : }
     999              : 
    1000              : /**
    1001              :  * @brief Set an asynchronous read request.
    1002              :  *
    1003              :  * @note This function is available only if @kconfig{CONFIG_ADC_ASYNC}
    1004              :  * is selected.
    1005              :  *
    1006              :  * If invoked from user mode, any sequence struct options for callback must
    1007              :  * be NULL.
    1008              :  *
    1009              :  * @param dev       Pointer to the device structure for the driver instance.
    1010              :  * @param sequence  Structure specifying requested sequence of samplings.
    1011              :  * @param async     Pointer to a valid and ready to be signaled struct
    1012              :  *                  k_poll_signal. (Note: if NULL this function will not notify
    1013              :  *                  the end of the transaction, and whether it went successfully
    1014              :  *                  or not).
    1015              :  *
    1016              :  * @returns 0 on success, negative error code otherwise.
    1017              :  *          See adc_read() for a list of possible error codes.
    1018              :  *
    1019              :  */
    1020            1 : __syscall int adc_read_async(const struct device *dev,
    1021              :                              const struct adc_sequence *sequence,
    1022              :                              struct k_poll_signal *async);
    1023              : 
    1024              : #ifdef CONFIG_ADC_ASYNC
    1025              : static inline int z_impl_adc_read_async(const struct device *dev,
    1026              :                                         const struct adc_sequence *sequence,
    1027              :                                         struct k_poll_signal *async)
    1028              : {
    1029              :         return DEVICE_API_GET(adc, dev)->read_async(dev, sequence, async);
    1030              : }
    1031              : #endif /* CONFIG_ADC_ASYNC */
    1032              : 
    1033              : #ifdef CONFIG_ADC_STREAM
    1034              : /**
    1035              :  * @brief Get decoder APIs for that device.
    1036              :  *
    1037              :  * @note This function is available only if @kconfig{CONFIG_ADC_STREAM}
    1038              :  * is selected.
    1039              :  *
    1040              :  * @param dev   Pointer to the device structure for the driver instance.
    1041              :  * @param api   Pointer to the decoder which will be set upon success.
    1042              :  *
    1043              :  * @returns 0 on success, negative error code otherwise.
    1044              :  *
    1045              :  *
    1046              :  */
    1047              : __syscall int adc_get_decoder(const struct device *dev,
    1048              :                                 const struct adc_decoder_api **api);
    1049              : /*
    1050              :  * Generic data structure used for encoding the sample timestamp and number of channels sampled.
    1051              :  */
    1052              : struct __attribute__((__packed__)) adc_data_generic_header {
    1053              :         /* The timestamp at which the data was collected from the adc */
    1054              :         uint64_t timestamp_ns;
    1055              : 
    1056              :         /*
    1057              :          * The number of channels present in the frame.
    1058              :          */
    1059              :         uint8_t num_channels;
    1060              : 
    1061              :         /* Shift value for all samples in the frame */
    1062              :         int8_t shift;
    1063              : 
    1064              :         /* This padding is needed to make sure that the 'channels' field is aligned */
    1065              :         int16_t _padding;
    1066              : 
    1067              :         /* Channels present in the frame */
    1068              :         struct adc_chan_spec channels[0];
    1069              : };
    1070              : 
    1071              : static inline int adc_stream(struct rtio_iodev *iodev, struct rtio *ctx, void *userdata,
    1072              :                                 struct rtio_sqe **handle)
    1073              : {
    1074              :         if (IS_ENABLED(CONFIG_USERSPACE)) {
    1075              :                 struct rtio_sqe sqe;
    1076              : 
    1077              :                 rtio_sqe_prep_read_multishot(&sqe, iodev, RTIO_PRIO_NORM, userdata);
    1078              :                 rtio_sqe_copy_in_get_handles(ctx, &sqe, handle, 1);
    1079              :         } else {
    1080              :                 struct rtio_sqe *sqe = rtio_sqe_acquire(ctx);
    1081              : 
    1082              :                 if (sqe == NULL) {
    1083              :                         return -ENOMEM;
    1084              :                 }
    1085              :                 if (handle != NULL) {
    1086              :                         *handle = sqe;
    1087              :                 }
    1088              :                 rtio_sqe_prep_read_multishot(sqe, iodev, RTIO_PRIO_NORM, userdata);
    1089              :         }
    1090              :         rtio_submit(ctx, 0);
    1091              :         return 0;
    1092              : }
    1093              : 
    1094              : static inline int z_impl_adc_get_decoder(const struct device *dev,
    1095              :                                             const struct adc_decoder_api **decoder)
    1096              : {
    1097              :         const struct adc_driver_api *api = DEVICE_API_GET(adc, dev);
    1098              : 
    1099              :         __ASSERT_NO_MSG(api != NULL);
    1100              : 
    1101              :         if (api->get_decoder == NULL) {
    1102              :                 *decoder = NULL;
    1103              :                 return -1;
    1104              :         }
    1105              : 
    1106              :         return api->get_decoder(dev, decoder);
    1107              : }
    1108              : #endif /* CONFIG_ADC_STREAM */
    1109              : 
    1110              : /**
    1111              :  * @brief Get the internal reference voltage.
    1112              :  *
    1113              :  * Returns the voltage corresponding to @ref ADC_REF_INTERNAL,
    1114              :  * measured in millivolts.
    1115              :  *
    1116              :  * @return a positive value is the reference voltage value.  Returns
    1117              :  * zero if reference voltage information is not available.
    1118              :  */
    1119            1 : static inline uint16_t adc_ref_internal(const struct device *dev)
    1120              : {
    1121              :         return DEVICE_API_GET(adc, dev)->ref_internal;
    1122              : }
    1123              : 
    1124              : /**
    1125              :  * @brief Conversion from raw ADC units to a specific output unit
    1126              :  *
    1127              :  * This function performs the necessary conversion to transform a raw
    1128              :  * ADC measurement to a physical voltage.
    1129              :  *
    1130              :  * @param ref_mv the reference voltage used for the measurement, in
    1131              :  * millivolts.  This may be from adc_ref_internal() or a known
    1132              :  * external reference.
    1133              :  *
    1134              :  * @param gain the ADC gain configuration used to sample the input
    1135              :  *
    1136              :  * @param resolution the number of bits in the absolute value of the
    1137              :  * sample.  For differential sampling this needs to be one less than the
    1138              :  * resolution in struct adc_sequence.
    1139              :  *
    1140              :  * @param valp pointer to the raw measurement value on input, and the
    1141              :  * corresponding output value on successful conversion.  If
    1142              :  * conversion fails the stored value is left unchanged.
    1143              :  *
    1144              :  * @retval 0 on successful conversion
    1145              :  * @retval -EINVAL if the gain is not reversible
    1146              :  */
    1147            1 : typedef int (*adc_raw_to_x_fn)(int32_t ref_mv, enum adc_gain gain, uint8_t resolution,
    1148              :                                int32_t *valp);
    1149              : 
    1150              : /**
    1151              :  * @brief Convert a raw ADC value to millivolts.
    1152              :  *
    1153              :  * @see adc_raw_to_x_fn
    1154              :  */
    1155            1 : static inline int adc_raw_to_millivolts(int32_t ref_mv, enum adc_gain gain, uint8_t resolution,
    1156              :                                         int32_t *valp)
    1157              : {
    1158              :         int32_t adc_mv = *valp * ref_mv;
    1159              :         int ret = adc_gain_invert(gain, &adc_mv);
    1160              : 
    1161              :         if (ret == 0) {
    1162              :                 *valp = (adc_mv >> resolution);
    1163              :         }
    1164              : 
    1165              :         return ret;
    1166              : }
    1167              : 
    1168              : /**
    1169              :  * @brief Convert a raw ADC value to microvolts.
    1170              :  *
    1171              :  * @see adc_raw_to_x_fn
    1172              :  */
    1173            1 : static inline int adc_raw_to_microvolts(int32_t ref_mv, enum adc_gain gain, uint8_t resolution,
    1174              :                                         int32_t *valp)
    1175              : {
    1176              :         int64_t adc_uv = (int64_t)*valp * ref_mv * 1000;
    1177              :         int ret = adc_gain_invert_64(gain, &adc_uv);
    1178              : 
    1179              :         if (ret == 0) {
    1180              :                 *valp = (int32_t)(adc_uv >> resolution);
    1181              :         }
    1182              : 
    1183              :         return ret;
    1184              : }
    1185              : 
    1186              : /**
    1187              :  * @brief Convert a raw ADC value to an arbitrary output unit
    1188              :  *
    1189              :  * @param[in] conv_func Function that converts to the final output unit.
    1190              :  * @param[in] spec ADC specification from Devicetree.
    1191              :  * @param[in] channel_cfg Channel configuration used for sampling. This can be
    1192              :  * either the configuration from @a spec, or an alternate sampling configuration
    1193              :  * based on @a spec, for example a different gain value.
    1194              :  * @param[in,out] valp Pointer to the raw measurement value on input, and the
    1195              :  * corresponding output value on successful conversion. If conversion fails
    1196              :  * the stored value is left unchanged.
    1197              :  *
    1198              :  * @return A value from adc_raw_to_x_fn or -ENOTSUP if information from
    1199              :  * Devicetree is not valid.
    1200              :  * @see adc_raw_to_x_fn
    1201              :  */
    1202            1 : static inline int adc_raw_to_x_dt_chan(adc_raw_to_x_fn conv_func,
    1203              :                                             const struct adc_dt_spec *spec,
    1204              :                                             const struct adc_channel_cfg *channel_cfg,
    1205              :                                             int32_t *valp)
    1206              : {
    1207              :         int32_t vref_mv;
    1208              :         uint8_t resolution;
    1209              : 
    1210              :         if (!spec->channel_cfg_dt_node_exists) {
    1211              :                 return -ENOTSUP;
    1212              :         }
    1213              : 
    1214              :         if (channel_cfg->reference == ADC_REF_INTERNAL) {
    1215              :                 vref_mv = (int32_t)adc_ref_internal(spec->dev);
    1216              :         } else {
    1217              :                 vref_mv = spec->vref_mv;
    1218              :         }
    1219              : 
    1220              :         resolution = spec->resolution;
    1221              : 
    1222              :         /*
    1223              :          * For differential channels, one bit less needs to be specified
    1224              :          * for resolution to achieve correct conversion.
    1225              :          */
    1226              :         if (channel_cfg->differential) {
    1227              :                 resolution -= 1U;
    1228              :         }
    1229              : 
    1230              :         return conv_func(vref_mv, channel_cfg->gain, resolution, valp);
    1231              : }
    1232              : 
    1233              : 
    1234              : /**
    1235              :  * @brief Convert a raw ADC value to millivolts using information stored
    1236              :  * in a struct adc_dt_spec.
    1237              :  *
    1238              :  * @param[in] spec ADC specification from Devicetree.
    1239              :  * @param[in,out] valp Pointer to the raw measurement value on input, and the
    1240              :  * corresponding millivolt value on successful conversion. If conversion fails
    1241              :  * the stored value is left unchanged.
    1242              :  *
    1243              :  * @return A value from adc_raw_to_millivolts() or -ENOTSUP if information from
    1244              :  * Devicetree is not valid.
    1245              :  * @see adc_raw_to_millivolts()
    1246              :  */
    1247            1 : static inline int adc_raw_to_millivolts_dt(const struct adc_dt_spec *spec, int32_t *valp)
    1248              : {
    1249              :         return adc_raw_to_x_dt_chan(adc_raw_to_millivolts, spec, &spec->channel_cfg, valp);
    1250              : }
    1251              : 
    1252              : /**
    1253              :  * @brief Convert a raw ADC value to microvolts using information stored
    1254              :  * in a struct adc_dt_spec.
    1255              :  *
    1256              :  * @param[in] spec ADC specification from Devicetree.
    1257              :  * @param[in,out] valp Pointer to the raw measurement value on input, and the
    1258              :  * corresponding microvolt value on successful conversion. If conversion fails
    1259              :  * the stored value is left unchanged.
    1260              :  *
    1261              :  * @return A value from adc_raw_to_microvolts() or -ENOTSUP if information from
    1262              :  * Devicetree is not valid.
    1263              :  * @see adc_raw_to_microvolts()
    1264              :  */
    1265            1 : static inline int adc_raw_to_microvolts_dt(const struct adc_dt_spec *spec, int32_t *valp)
    1266              : {
    1267              :         return adc_raw_to_x_dt_chan(adc_raw_to_microvolts, spec, &spec->channel_cfg, valp);
    1268              : }
    1269              : 
    1270              : /**
    1271              :  * @brief Initialize a struct adc_sequence from information stored in
    1272              :  * struct adc_dt_spec.
    1273              :  *
    1274              :  * Note that this function only initializes the following fields:
    1275              :  *
    1276              :  * - @ref adc_sequence.channels
    1277              :  * - @ref adc_sequence.resolution
    1278              :  * - @ref adc_sequence.oversampling
    1279              :  *
    1280              :  * Other fields should be initialized by the caller.
    1281              :  *
    1282              :  * @param[in] spec ADC specification from Devicetree.
    1283              :  * @param[out] seq Sequence to initialize.
    1284              :  *
    1285              :  * @retval 0 On success
    1286              :  * @retval -ENOTSUP If @p spec does not have valid channel configuration
    1287              :  */
    1288            1 : static inline int adc_sequence_init_dt(const struct adc_dt_spec *spec,
    1289              :                                        struct adc_sequence *seq)
    1290              : {
    1291              :         if (!spec->channel_cfg_dt_node_exists) {
    1292              :                 return -ENOTSUP;
    1293              :         }
    1294              : 
    1295              :         seq->channels = BIT(spec->channel_id);
    1296              :         seq->resolution = spec->resolution;
    1297              :         seq->oversampling = spec->oversampling;
    1298              : 
    1299              :         return 0;
    1300              : }
    1301              : 
    1302              : /**
    1303              :  * @brief Validate that the ADC device is ready.
    1304              :  *
    1305              :  * @param spec ADC specification from devicetree
    1306              :  *
    1307              :  * @retval true if the ADC device is ready for use and false otherwise.
    1308              :  */
    1309            1 : static inline bool adc_is_ready_dt(const struct adc_dt_spec *spec)
    1310              : {
    1311              :         return device_is_ready(spec->dev);
    1312              : }
    1313              : 
    1314              : /**
    1315              :  * @}
    1316              :  */
    1317              : 
    1318              : /**
    1319              :  * @brief Get the decoder name for the current driver
    1320              :  *
    1321              :  * This function depends on `DT_DRV_COMPAT` being defined.
    1322              :  */
    1323            1 : #define ADC_DECODER_NAME() UTIL_CAT(DT_DRV_COMPAT, __adc_decoder_api)
    1324              : 
    1325              : /**
    1326              :  * @brief Statically get the decoder for a given node
    1327              :  *
    1328              :  * @code{.c}
    1329              :  * static const adc_decoder_api *decoder = ADC_DECODER_DT_GET(DT_ALIAS(adc));
    1330              :  * @endcode
    1331              :  */
    1332            1 : #define ADC_DECODER_DT_GET(node_id)                                                             \
    1333              :         &UTIL_CAT(DT_STRING_TOKEN_BY_IDX(node_id, compatible, 0), __adc_decoder_api)
    1334              : 
    1335              : /**
    1336              :  * @brief Define a decoder API
    1337              :  *
    1338              :  * This macro should be created once per compatible string of a adc and will create a statically
    1339              :  * referenceable decoder API.
    1340              :  *
    1341              :  * @code{.c}
    1342              :  * ADC_DECODER_API_DT_DEFINE() = {
    1343              :  *   .get_frame_count = my_driver_get_frame_count,
    1344              :  *   .get_timestamp = my_driver_get_timestamp,
    1345              :  *   .get_shift = my_driver_get_shift,
    1346              :  *   .decode = my_driver_decode,
    1347              :  * };
    1348              :  * @endcode
    1349              :  */
    1350            1 : #define ADC_DECODER_API_DT_DEFINE()                                                             \
    1351              :         COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT), (), (static))                     \
    1352              :         const STRUCT_SECTION_ITERABLE(adc_decoder_api, ADC_DECODER_NAME())
    1353              : 
    1354              : #define Z_MAYBE_ADC_DECODER_DECLARE_INTERNAL_IDX(node_id, prop, idx)                            \
    1355              :         extern const struct adc_decoder_api UTIL_CAT(                                           \
    1356              :                 DT_STRING_TOKEN_BY_IDX(node_id, prop, idx), __adc_decoder_api);
    1357              : 
    1358              : #define Z_MAYBE_ADC_DECODER_DECLARE_INTERNAL(node_id)                                           \
    1359              :         COND_CODE_1(DT_NODE_HAS_PROP(node_id, compatible),                                      \
    1360              :                         (DT_FOREACH_PROP_ELEM(node_id, compatible,                              \
    1361              :                                           Z_MAYBE_ADC_DECODER_DECLARE_INTERNAL_IDX)),           \
    1362              :                                                 ())
    1363              : 
    1364            0 : DT_FOREACH_STATUS_OKAY_NODE(Z_MAYBE_ADC_DECODER_DECLARE_INTERNAL)
    1365              : 
    1366              : /* The default adc iodev API */
    1367              : extern const struct rtio_iodev_api __adc_iodev_api;
    1368              : 
    1369            0 : #define ADC_DT_STREAM_IODEV(name, dt_node, adc_dt_spec, ...)                                    \
    1370              :         static struct adc_stream_trigger _CONCAT(__trigger_array_, name)[] = {__VA_ARGS__};     \
    1371              :         static struct adc_read_config _CONCAT(__adc_read_config_, name) = {                     \
    1372              :                 .adc = DEVICE_DT_GET(dt_node),                                                  \
    1373              :                 .is_streaming = true,                                                           \
    1374              :                 .adc_spec = adc_dt_spec,                                                        \
    1375              :                 .triggers = _CONCAT(__trigger_array_, name),                                    \
    1376              :                 .adc_spec_cnt = ARRAY_SIZE(adc_dt_spec),                                        \
    1377              :                 .trigger_cnt = ARRAY_SIZE(_CONCAT(__trigger_array_, name)),                     \
    1378              :         };                                                                                      \
    1379              :         RTIO_IODEV_DEFINE(name, &__adc_iodev_api, &_CONCAT(__adc_read_config_, name))
    1380              : 
    1381              : #ifdef __cplusplus
    1382              : }
    1383              : #endif
    1384              : 
    1385              : #include <zephyr/syscalls/adc.h>
    1386              : 
    1387              : #endif  /* ZEPHYR_INCLUDE_DRIVERS_ADC_H_ */
        

Generated by: LCOV version 2.0-1