LCOV - code coverage report
Current view: top level - zephyr/drivers - sensor.h Coverage Total Hit
Test: new.info Lines: 67.3 % 107 72
Test Date: 2025-09-05 16:43:28

            Line data    Source code
       1            1 : /**
       2              :  * @file drivers/sensor.h
       3              :  *
       4              :  * @brief Public APIs for the sensor driver.
       5              :  */
       6              : 
       7              : /*
       8              :  * Copyright (c) 2016 Intel Corporation
       9              :  *
      10              :  * SPDX-License-Identifier: Apache-2.0
      11              :  */
      12              : #ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_H_
      13              : #define ZEPHYR_INCLUDE_DRIVERS_SENSOR_H_
      14              : 
      15              : /**
      16              :  * @brief Sensor Interface
      17              :  * @defgroup sensor_interface Sensor Interface
      18              :  * @since 1.2
      19              :  * @version 1.0.0
      20              :  * @ingroup io_interfaces
      21              :  * @{
      22              :  *
      23              :  * @defgroup sensor_interface_ext Device-specific Sensor API extensions
      24              :  * @{
      25              :  * @}
      26              :  */
      27              : 
      28              : #include <errno.h>
      29              : #include <stdlib.h>
      30              : 
      31              : #include <zephyr/device.h>
      32              : #include <zephyr/drivers/sensor_data_types.h>
      33              : #include <zephyr/dsp/types.h>
      34              : #include <zephyr/rtio/rtio.h>
      35              : #include <zephyr/sys/iterable_sections.h>
      36              : #include <zephyr/types.h>
      37              : 
      38              : #ifdef __cplusplus
      39              : extern "C" {
      40              : #endif
      41              : 
      42              : /**
      43              :  * @brief Representation of a sensor readout value.
      44              :  *
      45              :  * The value is represented as having an integer and a fractional part,
      46              :  * and can be obtained using the formula val1 + val2 * 10^(-6). Negative
      47              :  * values also adhere to the above formula, but may need special attention.
      48              :  * Here are some examples of the value representation:
      49              :  *
      50              :  *      0.5: val1 =  0, val2 =  500000
      51              :  *     -0.5: val1 =  0, val2 = -500000
      52              :  *     -1.0: val1 = -1, val2 =  0
      53              :  *     -1.5: val1 = -1, val2 = -500000
      54              :  */
      55            1 : struct sensor_value {
      56              :         /** Integer part of the value. */
      57            1 :         int32_t val1;
      58              :         /** Fractional part of the value (in one-millionth parts). */
      59            1 :         int32_t val2;
      60              : };
      61              : 
      62              : /**
      63              :  * @brief Sensor channels.
      64              :  */
      65            1 : enum sensor_channel {
      66              :         /** Acceleration on the X axis, in m/s^2. */
      67              :         SENSOR_CHAN_ACCEL_X,
      68              :         /** Acceleration on the Y axis, in m/s^2. */
      69              :         SENSOR_CHAN_ACCEL_Y,
      70              :         /** Acceleration on the Z axis, in m/s^2. */
      71              :         SENSOR_CHAN_ACCEL_Z,
      72              :         /** Acceleration on the X, Y and Z axes. */
      73              :         SENSOR_CHAN_ACCEL_XYZ,
      74              :         /** Angular velocity around the X axis, in radians/s. */
      75              :         SENSOR_CHAN_GYRO_X,
      76              :         /** Angular velocity around the Y axis, in radians/s. */
      77              :         SENSOR_CHAN_GYRO_Y,
      78              :         /** Angular velocity around the Z axis, in radians/s. */
      79              :         SENSOR_CHAN_GYRO_Z,
      80              :         /** Angular velocity around the X, Y and Z axes. */
      81              :         SENSOR_CHAN_GYRO_XYZ,
      82              :         /** Magnetic field on the X axis, in Gauss. */
      83              :         SENSOR_CHAN_MAGN_X,
      84              :         /** Magnetic field on the Y axis, in Gauss. */
      85              :         SENSOR_CHAN_MAGN_Y,
      86              :         /** Magnetic field on the Z axis, in Gauss. */
      87              :         SENSOR_CHAN_MAGN_Z,
      88              :         /** Magnetic field on the X, Y and Z axes. */
      89              :         SENSOR_CHAN_MAGN_XYZ,
      90              :         /** Device die temperature in degrees Celsius. */
      91              :         SENSOR_CHAN_DIE_TEMP,
      92              :         /** Ambient temperature in degrees Celsius. */
      93              :         SENSOR_CHAN_AMBIENT_TEMP,
      94              :         /** Pressure in kilopascal. */
      95              :         SENSOR_CHAN_PRESS,
      96              :         /**
      97              :          * Proximity.  Adimensional.  A value of 1 indicates that an
      98              :          * object is close.
      99              :          */
     100              :         SENSOR_CHAN_PROX,
     101              :         /** Humidity, in percent. */
     102              :         SENSOR_CHAN_HUMIDITY,
     103              :         /** Illuminance in visible spectrum, in lux. */
     104              :         SENSOR_CHAN_LIGHT,
     105              :         /** Illuminance in infra-red spectrum, in lux. */
     106              :         SENSOR_CHAN_IR,
     107              :         /** Illuminance in red spectrum, in lux. */
     108              :         SENSOR_CHAN_RED,
     109              :         /** Illuminance in green spectrum, in lux. */
     110              :         SENSOR_CHAN_GREEN,
     111              :         /** Illuminance in blue spectrum, in lux. */
     112              :         SENSOR_CHAN_BLUE,
     113              :         /** Altitude, in meters */
     114              :         SENSOR_CHAN_ALTITUDE,
     115              : 
     116              :         /** 1.0 micro-meters Particulate Matter, in ug/m^3 */
     117              :         SENSOR_CHAN_PM_1_0,
     118              :         /** 2.5 micro-meters Particulate Matter, in ug/m^3 */
     119              :         SENSOR_CHAN_PM_2_5,
     120              :         /** 10 micro-meters Particulate Matter, in ug/m^3 */
     121              :         SENSOR_CHAN_PM_10,
     122              :         /** Distance. From sensor to target, in meters */
     123              :         SENSOR_CHAN_DISTANCE,
     124              : 
     125              :         /** CO2 level, in parts per million (ppm) **/
     126              :         SENSOR_CHAN_CO2,
     127              :         /** O2 level, in parts per million (ppm) **/
     128              :         SENSOR_CHAN_O2,
     129              :         /** VOC level, in parts per billion (ppb) **/
     130              :         SENSOR_CHAN_VOC,
     131              :         /** Gas sensor resistance in ohms. */
     132              :         SENSOR_CHAN_GAS_RES,
     133              : 
     134              :         /** Voltage, in volts **/
     135              :         SENSOR_CHAN_VOLTAGE,
     136              : 
     137              :         /** Current Shunt Voltage in milli-volts **/
     138              :         SENSOR_CHAN_VSHUNT,
     139              : 
     140              :         /** Current, in amps **/
     141              :         SENSOR_CHAN_CURRENT,
     142              :         /** Power in watts **/
     143              :         SENSOR_CHAN_POWER,
     144              : 
     145              :         /** Resistance , in Ohm **/
     146              :         SENSOR_CHAN_RESISTANCE,
     147              : 
     148              :         /** Angular rotation, in degrees */
     149              :         SENSOR_CHAN_ROTATION,
     150              : 
     151              :         /** Position change on the X axis, in points. */
     152              :         SENSOR_CHAN_POS_DX,
     153              :         /** Position change on the Y axis, in points. */
     154              :         SENSOR_CHAN_POS_DY,
     155              :         /** Position change on the Z axis, in points. */
     156              :         SENSOR_CHAN_POS_DZ,
     157              :         /** Position change on the X, Y and Z axis, in points. */
     158              :         SENSOR_CHAN_POS_DXYZ,
     159              : 
     160              :         /** Revolutions per minute, in RPM. */
     161              :         SENSOR_CHAN_RPM,
     162              : 
     163              :         /** Frequency, in Hz. */
     164              :         SENSOR_CHAN_FREQUENCY,
     165              : 
     166              :         /** Voltage, in volts **/
     167              :         SENSOR_CHAN_GAUGE_VOLTAGE,
     168              :         /** Average current, in amps (negative=discharging) **/
     169              :         SENSOR_CHAN_GAUGE_AVG_CURRENT,
     170              :         /** Standby current, in amps (negative=discharging) **/
     171              :         SENSOR_CHAN_GAUGE_STDBY_CURRENT,
     172              :         /** Max load current, in amps (negative=discharging) **/
     173              :         SENSOR_CHAN_GAUGE_MAX_LOAD_CURRENT,
     174              :         /** Gauge temperature  **/
     175              :         SENSOR_CHAN_GAUGE_TEMP,
     176              :         /** State of charge measurement in % **/
     177              :         SENSOR_CHAN_GAUGE_STATE_OF_CHARGE,
     178              :         /** Full Charge Capacity in mAh **/
     179              :         SENSOR_CHAN_GAUGE_FULL_CHARGE_CAPACITY,
     180              :         /** Remaining Charge Capacity in mAh **/
     181              :         SENSOR_CHAN_GAUGE_REMAINING_CHARGE_CAPACITY,
     182              :         /** Nominal Available Capacity in mAh **/
     183              :         SENSOR_CHAN_GAUGE_NOM_AVAIL_CAPACITY,
     184              :         /** Full Available Capacity in mAh **/
     185              :         SENSOR_CHAN_GAUGE_FULL_AVAIL_CAPACITY,
     186              :         /** Average power in mW **/
     187              :         SENSOR_CHAN_GAUGE_AVG_POWER,
     188              :         /** State of health measurement in % **/
     189              :         SENSOR_CHAN_GAUGE_STATE_OF_HEALTH,
     190              :         /** Time to empty in minutes **/
     191              :         SENSOR_CHAN_GAUGE_TIME_TO_EMPTY,
     192              :         /** Time to full in minutes **/
     193              :         SENSOR_CHAN_GAUGE_TIME_TO_FULL,
     194              :         /** Cycle count (total number of charge/discharge cycles) **/
     195              :         SENSOR_CHAN_GAUGE_CYCLE_COUNT,
     196              :         /** Design voltage of cell in V (max voltage)*/
     197              :         SENSOR_CHAN_GAUGE_DESIGN_VOLTAGE,
     198              :         /** Desired voltage of cell in V (nominal voltage) */
     199              :         SENSOR_CHAN_GAUGE_DESIRED_VOLTAGE,
     200              :         /** Desired charging current in mA */
     201              :         SENSOR_CHAN_GAUGE_DESIRED_CHARGING_CURRENT,
     202              :         /** Game Rotation Vector (unit quaternion components X/Y/Z/W) */
     203              :         SENSOR_CHAN_GAME_ROTATION_VECTOR,
     204              :         /** Gravity Vector (X/Y/Z components in m/s^2) */
     205              :         SENSOR_CHAN_GRAVITY_VECTOR,
     206              :         /** Gyroscope bias (X/Y/Z components in radians/s) */
     207              :         SENSOR_CHAN_GBIAS_XYZ,
     208              : 
     209              :         /** All channels. */
     210              :         SENSOR_CHAN_ALL,
     211              : 
     212              :         /**
     213              :          * Number of all common sensor channels.
     214              :          */
     215              :         SENSOR_CHAN_COMMON_COUNT,
     216              : 
     217              :         /**
     218              :          * This and higher values are sensor specific.
     219              :          * Refer to the sensor header file.
     220              :          */
     221              :         SENSOR_CHAN_PRIV_START = SENSOR_CHAN_COMMON_COUNT,
     222              : 
     223              :         /**
     224              :          * Maximum value describing a sensor channel type.
     225              :          */
     226              :         SENSOR_CHAN_MAX = INT16_MAX,
     227              : };
     228              : 
     229              : /**
     230              :  * @brief Sensor trigger types.
     231              :  */
     232            1 : enum sensor_trigger_type {
     233              :         /**
     234              :          * Timer-based trigger, useful when the sensor does not have an
     235              :          * interrupt line.
     236              :          */
     237              :         SENSOR_TRIG_TIMER,
     238              :         /** Trigger fires whenever new data is ready. */
     239              :         SENSOR_TRIG_DATA_READY,
     240              :         /**
     241              :          * Trigger fires when the selected channel varies significantly.
     242              :          * This includes any-motion detection when the channel is
     243              :          * acceleration or gyro. If detection is based on slope between
     244              :          * successive channel readings, the slope threshold is configured
     245              :          * via the @ref SENSOR_ATTR_SLOPE_TH and @ref SENSOR_ATTR_SLOPE_DUR
     246              :          * attributes.
     247              :          */
     248              :         SENSOR_TRIG_DELTA,
     249              :         /** Trigger fires when a near/far event is detected. */
     250              :         SENSOR_TRIG_NEAR_FAR,
     251              :         /**
     252              :          * Trigger fires when channel reading transitions configured
     253              :          * thresholds.  The thresholds are configured via the @ref
     254              :          * SENSOR_ATTR_LOWER_THRESH, @ref SENSOR_ATTR_UPPER_THRESH, and
     255              :          * @ref SENSOR_ATTR_HYSTERESIS attributes.
     256              :          */
     257              :         SENSOR_TRIG_THRESHOLD,
     258              : 
     259              :         /** Trigger fires when a single tap is detected. */
     260              :         SENSOR_TRIG_TAP,
     261              : 
     262              :         /** Trigger fires when a double tap is detected. */
     263              :         SENSOR_TRIG_DOUBLE_TAP,
     264              : 
     265              :         /** Trigger fires when a free fall is detected. */
     266              :         SENSOR_TRIG_FREEFALL,
     267              : 
     268              :         /** Trigger fires when motion is detected. */
     269              :         SENSOR_TRIG_MOTION,
     270              : 
     271              :         /** Trigger fires when no motion has been detected for a while. */
     272              :         SENSOR_TRIG_STATIONARY,
     273              : 
     274              :         /** Trigger fires when the FIFO watermark has been reached. */
     275              :         SENSOR_TRIG_FIFO_WATERMARK,
     276              : 
     277              :         /** Trigger fires when the FIFO becomes full. */
     278              :         SENSOR_TRIG_FIFO_FULL,
     279              : 
     280              :         /** Trigger fires when a tilt is detected. */
     281              :         SENSOR_TRIG_TILT,
     282              : 
     283              :         /**
     284              :          * Number of all common sensor triggers.
     285              :          */
     286              :         SENSOR_TRIG_COMMON_COUNT,
     287              : 
     288              :         /**
     289              :          * This and higher values are sensor specific.
     290              :          * Refer to the sensor header file.
     291              :          */
     292              :         SENSOR_TRIG_PRIV_START = SENSOR_TRIG_COMMON_COUNT,
     293              : 
     294              :         /**
     295              :          * Maximum value describing a sensor trigger type.
     296              :          */
     297              :         SENSOR_TRIG_MAX = INT16_MAX,
     298              : };
     299              : 
     300              : /**
     301              :  * @brief Sensor trigger spec.
     302              :  */
     303            1 : struct sensor_trigger {
     304              :         /** Trigger type. */
     305            1 :         enum sensor_trigger_type type;
     306              :         /** Channel the trigger is set on. */
     307            1 :         enum sensor_channel chan;
     308              : };
     309              : 
     310              : /**
     311              :  * @brief Sensor attribute types.
     312              :  */
     313            0 : enum sensor_attribute {
     314              :         /**
     315              :          * Sensor sampling frequency, i.e. how many times a second the
     316              :          * sensor takes a measurement.
     317              :          */
     318              :         SENSOR_ATTR_SAMPLING_FREQUENCY,
     319              :         /** Lower threshold for trigger. */
     320              :         SENSOR_ATTR_LOWER_THRESH,
     321              :         /** Upper threshold for trigger. */
     322              :         SENSOR_ATTR_UPPER_THRESH,
     323              :         /** Threshold for any-motion (slope) trigger. */
     324              :         SENSOR_ATTR_SLOPE_TH,
     325              :         /**
     326              :          * Duration for which the slope values needs to be
     327              :          * outside the threshold for the trigger to fire.
     328              :          */
     329              :         SENSOR_ATTR_SLOPE_DUR,
     330              :         /* Hysteresis for trigger thresholds. */
     331              :         SENSOR_ATTR_HYSTERESIS,
     332              :         /** Oversampling factor */
     333              :         SENSOR_ATTR_OVERSAMPLING,
     334              :         /** Sensor range, in SI units. */
     335              :         SENSOR_ATTR_FULL_SCALE,
     336              :         /**
     337              :          * The sensor value returned will be altered by the amount indicated by
     338              :          * offset: final_value = sensor_value + offset.
     339              :          */
     340              :         SENSOR_ATTR_OFFSET,
     341              :         /**
     342              :          * Calibration target. This will be used by the internal chip's
     343              :          * algorithms to calibrate itself on a certain axis, or all of them.
     344              :          */
     345              :         SENSOR_ATTR_CALIB_TARGET,
     346              :         /** Configure the operating modes of a sensor. */
     347              :         SENSOR_ATTR_CONFIGURATION,
     348              :         /** Set a calibration value needed by a sensor. */
     349              :         SENSOR_ATTR_CALIBRATION,
     350              :         /** Enable/disable sensor features */
     351              :         SENSOR_ATTR_FEATURE_MASK,
     352              :         /** Alert threshold or alert enable/disable */
     353              :         SENSOR_ATTR_ALERT,
     354              :         /** Free-fall duration represented in milliseconds.
     355              :          *  If the sampling frequency is changed during runtime,
     356              :          *  this attribute should be set to adjust freefall duration
     357              :          *  to the new sampling frequency.
     358              :          */
     359              :         SENSOR_ATTR_FF_DUR,
     360              : 
     361              :         /** Hardware batch duration in ticks */
     362              :         SENSOR_ATTR_BATCH_DURATION,
     363              :         /* Configure the gain of a sensor. */
     364              :         SENSOR_ATTR_GAIN,
     365              :         /* Configure the resolution of a sensor. */
     366              :         SENSOR_ATTR_RESOLUTION,
     367              :         /**
     368              :          * Number of all common sensor attributes.
     369              :          */
     370              :         SENSOR_ATTR_COMMON_COUNT,
     371              : 
     372              :         /**
     373              :          * This and higher values are sensor specific.
     374              :          * Refer to the sensor header file.
     375              :          */
     376              :         SENSOR_ATTR_PRIV_START = SENSOR_ATTR_COMMON_COUNT,
     377              : 
     378              :         /**
     379              :          * Maximum value describing a sensor attribute type.
     380              :          */
     381              :         SENSOR_ATTR_MAX = INT16_MAX,
     382              : };
     383              : 
     384              : /**
     385              :  * @typedef sensor_trigger_handler_t
     386              :  * @brief Callback API upon firing of a trigger
     387              :  *
     388              :  * @param dev Pointer to the sensor device
     389              :  * @param trigger The trigger
     390              :  */
     391            1 : typedef void (*sensor_trigger_handler_t)(const struct device *dev,
     392              :                                          const struct sensor_trigger *trigger);
     393              : 
     394              : /**
     395              :  * @typedef sensor_attr_set_t
     396              :  * @brief Callback API upon setting a sensor's attributes
     397              :  *
     398              :  * See sensor_attr_set() for argument description
     399              :  */
     400            1 : typedef int (*sensor_attr_set_t)(const struct device *dev,
     401              :                                  enum sensor_channel chan,
     402              :                                  enum sensor_attribute attr,
     403              :                                  const struct sensor_value *val);
     404              : 
     405              : /**
     406              :  * @typedef sensor_attr_get_t
     407              :  * @brief Callback API upon getting a sensor's attributes
     408              :  *
     409              :  * See sensor_attr_get() for argument description
     410              :  */
     411            1 : typedef int (*sensor_attr_get_t)(const struct device *dev,
     412              :                                  enum sensor_channel chan,
     413              :                                  enum sensor_attribute attr,
     414              :                                  struct sensor_value *val);
     415              : 
     416              : /**
     417              :  * @typedef sensor_trigger_set_t
     418              :  * @brief Callback API for setting a sensor's trigger and handler
     419              :  *
     420              :  * See sensor_trigger_set() for argument description
     421              :  */
     422            1 : typedef int (*sensor_trigger_set_t)(const struct device *dev,
     423              :                                     const struct sensor_trigger *trig,
     424              :                                     sensor_trigger_handler_t handler);
     425              : /**
     426              :  * @typedef sensor_sample_fetch_t
     427              :  * @brief Callback API for fetching data from a sensor
     428              :  *
     429              :  * See sensor_sample_fetch() for argument description
     430              :  */
     431            1 : typedef int (*sensor_sample_fetch_t)(const struct device *dev,
     432              :                                      enum sensor_channel chan);
     433              : /**
     434              :  * @typedef sensor_channel_get_t
     435              :  * @brief Callback API for getting a reading from a sensor
     436              :  *
     437              :  * See sensor_channel_get() for argument description
     438              :  */
     439            1 : typedef int (*sensor_channel_get_t)(const struct device *dev,
     440              :                                     enum sensor_channel chan,
     441              :                                     struct sensor_value *val);
     442              : 
     443              : /**
     444              :  * @brief Sensor Channel Specification
     445              :  *
     446              :  * A sensor channel specification is a unique identifier per sensor device describing
     447              :  * a measurement channel.
     448              :  *
     449              :  * @note Typically passed by value as the size of a sensor_chan_spec is a single word.
     450              :  */
     451            1 : struct sensor_chan_spec {
     452            1 :         uint16_t chan_type; /**< A sensor channel type */
     453            1 :         uint16_t chan_idx;  /**< A sensor channel index */
     454              : };
     455              : 
     456              : /** @cond INTERNAL_HIDDEN */
     457              : /* Ensure sensor_chan_spec is sensibly sized to pass by value */
     458              : BUILD_ASSERT(sizeof(struct sensor_chan_spec) <= sizeof(uintptr_t),
     459              :              "sensor_chan_spec size should be equal or less than the size of a machine word");
     460              : /** @endcond */
     461              : 
     462              : /**
     463              :  * @brief Check if channel specs are equivalent
     464              :  *
     465              :  * @param chan_spec0 First chan spec
     466              :  * @param chan_spec1 Second chan spec
     467              :  * @retval true If equivalent
     468              :  * @retval false If not equivalent
     469              :  */
     470            1 : static inline bool sensor_chan_spec_eq(struct sensor_chan_spec chan_spec0,
     471              :                                        struct sensor_chan_spec chan_spec1)
     472              : {
     473              :         return chan_spec0.chan_type == chan_spec1.chan_type &&
     474              :                 chan_spec0.chan_idx == chan_spec1.chan_idx;
     475              : }
     476              : 
     477              : /**
     478              :  * @brief Decodes a single raw data buffer
     479              :  *
     480              :  * Data buffers are provided on the @ref rtio context that's supplied to
     481              :  * @ref sensor_read.
     482              :  */
     483            1 : struct sensor_decoder_api {
     484              :         /**
     485              :          * @brief Get the number of frames in the current buffer.
     486              :          *
     487              :          * @param[in]  buffer The buffer provided on the @ref rtio context.
     488              :          * @param[in]  channel The channel to get the count for
     489              :          * @param[out] frame_count The number of frames on the buffer (at least 1)
     490              :          * @return 0 on success
     491              :          * @return -ENOTSUP if the channel/channel_idx aren't found
     492              :          */
     493            1 :         int (*get_frame_count)(const uint8_t *buffer, struct sensor_chan_spec channel,
     494              :                                uint16_t *frame_count);
     495              : 
     496              :         /**
     497              :          * @brief Get the size required to decode a given channel
     498              :          *
     499              :          * When decoding a single frame, use @p base_size. For every additional frame, add another
     500              :          * @p frame_size. As an example, to decode 3 frames use: 'base_size + 2 * frame_size'.
     501              :          *
     502              :          * @param[in]  channel The channel to query
     503              :          * @param[out] base_size The size of decoding the first frame
     504              :          * @param[out] frame_size The additional size of every additional frame
     505              :          * @return 0 on success
     506              :          * @return -ENOTSUP if the channel is not supported
     507              :          */
     508            1 :         int (*get_size_info)(struct sensor_chan_spec channel, size_t *base_size,
     509              :                              size_t *frame_size);
     510              : 
     511              :         /**
     512              :          * @brief Decode up to @p max_count samples from the buffer
     513              :          *
     514              :          * Decode samples of channel @ref sensor_channel across multiple frames. If there exist
     515              :          * multiple instances of the same channel, @p channel_index is used to differentiate them.
     516              :          * As an example, assume a sensor provides 2 distance measurements:
     517              :          *
     518              :          * @code{.c}
     519              :          * // Decode the first channel instance of 'distance'
     520              :          * decoder->decode(buffer, SENSOR_CHAN_DISTANCE, 0, &fit, 5, out);
     521              :          * ...
     522              :          *
     523              :          * // Decode the second channel instance of 'distance'
     524              :          * decoder->decode(buffer, SENSOR_CHAN_DISTANCE, 1, &fit, 5, out);
     525              :          * @endcode
     526              :          *
     527              :          * @param[in]     buffer The buffer provided on the @ref rtio context
     528              :          * @param[in]     channel The channel to decode
     529              :          * @param[in,out] fit The current frame iterator
     530              :          * @param[in]     max_count The maximum number of channels to decode.
     531              :          * @param[out]    data_out The decoded data
     532              :          * @return 0 no more samples to decode
     533              :          * @return >0 the number of decoded frames
     534              :          * @return <0 on error
     535              :          */
     536            1 :         int (*decode)(const uint8_t *buffer, struct sensor_chan_spec channel, uint32_t *fit,
     537              :                       uint16_t max_count, void *data_out);
     538              : 
     539              :         /**
     540              :          * @brief Check if the given trigger type is present
     541              :          *
     542              :          * @param[in] buffer The buffer provided on the @ref rtio context
     543              :          * @param[in] trigger The trigger type in question
     544              :          * @return Whether the trigger is present in the buffer
     545              :          */
     546            1 :         bool (*has_trigger)(const uint8_t *buffer, enum sensor_trigger_type trigger);
     547              : };
     548              : 
     549              : /**
     550              :  * @brief Used for iterating over the data frames via the sensor_decoder_api.
     551              :  *
     552              :  * Example usage:
     553              :  *
     554              :  * @code(.c)
     555              :  *     struct sensor_decode_context ctx = SENSOR_DECODE_CONTEXT_INIT(
     556              :  *         decoder, buffer, SENSOR_CHAN_ACCEL_XYZ, 0);
     557              :  *
     558              :  *     while (true) {
     559              :  *       struct sensor_three_axis_data accel_out_data;
     560              :  *
     561              :  *       num_decoded_channels = sensor_decode(ctx, &accel_out_data, 1);
     562              :  *
     563              :  *       if (num_decoded_channels <= 0) {
     564              :  *         printk("Done decoding buffer\n");
     565              :  *         break;
     566              :  *       }
     567              :  *
     568              :  *       printk("Decoded (%" PRId32 ", %" PRId32 ", %" PRId32 ")\n", accel_out_data.readings[0].x,
     569              :  *           accel_out_data.readings[0].y, accel_out_data.readings[0].z);
     570              :  *     }
     571              :  * @endcode
     572              :  */
     573            1 : struct sensor_decode_context {
     574            0 :         const struct sensor_decoder_api *decoder;
     575            0 :         const uint8_t *buffer;
     576            0 :         struct sensor_chan_spec channel;
     577            0 :         uint32_t fit;
     578              : };
     579              : 
     580              : /**
     581              :  * @brief Initialize a sensor_decode_context
     582              :  */
     583            1 : #define SENSOR_DECODE_CONTEXT_INIT(decoder_, buffer_, channel_type_, channel_index_)               \
     584              :         {                                                                                          \
     585              :                 .decoder = (decoder_),                                                             \
     586              :                 .buffer = (buffer_),                                                               \
     587              :                 .channel = {.chan_type = (channel_type_), .chan_idx = (channel_index_)},           \
     588              :                 .fit = 0,                                                                          \
     589              :         }
     590              : 
     591              : /**
     592              :  * @brief Decode N frames using a sensor_decode_context
     593              :  *
     594              :  * @param[in,out] ctx The context to use for decoding
     595              :  * @param[out]    out The output buffer
     596              :  * @param[in]     max_count Maximum number of frames to decode
     597              :  * @return The decode result from sensor_decoder_api's decode function
     598              :  */
     599            1 : static inline int sensor_decode(struct sensor_decode_context *ctx, void *out, uint16_t max_count)
     600              : {
     601              :         return ctx->decoder->decode(ctx->buffer, ctx->channel, &ctx->fit, max_count, out);
     602              : }
     603              : 
     604            0 : int sensor_natively_supported_channel_size_info(struct sensor_chan_spec channel, size_t *base_size,
     605              :                                                 size_t *frame_size);
     606              : 
     607              : /**
     608              :  * @typedef sensor_get_decoder_t
     609              :  * @brief Get the decoder associate with the given device
     610              :  *
     611              :  * @see sensor_get_decoder for more details
     612              :  */
     613            1 : typedef int (*sensor_get_decoder_t)(const struct device *dev,
     614              :                                     const struct sensor_decoder_api **api);
     615              : 
     616              : /**
     617              :  * @brief Options for what to do with the associated data when a trigger is consumed
     618              :  */
     619            1 : enum sensor_stream_data_opt {
     620              :         /** @brief Include whatever data is associated with the trigger */
     621              :         SENSOR_STREAM_DATA_INCLUDE = 0,
     622              :         /** @brief Do nothing with the associated trigger data, it may be consumed later */
     623              :         SENSOR_STREAM_DATA_NOP = 1,
     624              :         /** @brief Flush/clear whatever data is associated with the trigger */
     625              :         SENSOR_STREAM_DATA_DROP = 2,
     626              : };
     627              : 
     628            0 : struct sensor_stream_trigger {
     629            0 :         enum sensor_trigger_type trigger;
     630            0 :         enum sensor_stream_data_opt opt;
     631              : };
     632              : 
     633            0 : #define SENSOR_STREAM_TRIGGER_PREP(_trigger, _opt)                                                 \
     634              :         {                                                                                          \
     635              :                 .trigger = (_trigger), .opt = (_opt),                                              \
     636              :         }
     637              : 
     638              : /*
     639              :  * Internal data structure used to store information about the IODevice for async reading and
     640              :  * streaming sensor data.
     641              :  */
     642            0 : struct sensor_read_config {
     643            0 :         const struct device *sensor;
     644            0 :         const bool is_streaming;
     645              :         union {
     646            0 :                 struct sensor_chan_spec *const channels;
     647            0 :                 struct sensor_stream_trigger *const triggers;
     648            0 :         };
     649            0 :         size_t count;
     650            0 :         const size_t max;
     651              : };
     652              : 
     653              : /**
     654              :  * @brief Define a reading instance of a sensor
     655              :  *
     656              :  * Use this macro to generate a @ref rtio_iodev for reading specific channels. Example:
     657              :  *
     658              :  * @code(.c)
     659              :  * SENSOR_DT_READ_IODEV(icm42688_accelgyro, DT_NODELABEL(icm42688),
     660              :  *     { SENSOR_CHAN_ACCEL_XYZ, 0 },
     661              :  *     { SENSOR_CHAN_GYRO_XYZ, 0 });
     662              :  *
     663              :  * int main(void) {
     664              :  *   sensor_read_async_mempool(&icm42688_accelgyro, &rtio);
     665              :  * }
     666              :  * @endcode
     667              :  */
     668            1 : #define SENSOR_DT_READ_IODEV(name, dt_node, ...)                                                   \
     669              :         static struct sensor_chan_spec _CONCAT(__channel_array_, name)[] = {__VA_ARGS__};          \
     670              :         static struct sensor_read_config _CONCAT(__sensor_read_config_, name) = {                  \
     671              :                 .sensor = DEVICE_DT_GET(dt_node),                                                  \
     672              :                 .is_streaming = false,                                                             \
     673              :                 .channels = _CONCAT(__channel_array_, name),                                       \
     674              :                 .count = ARRAY_SIZE(_CONCAT(__channel_array_, name)),                              \
     675              :                 .max = ARRAY_SIZE(_CONCAT(__channel_array_, name)),                                \
     676              :         };                                                                                         \
     677              :         RTIO_IODEV_DEFINE(name, &__sensor_iodev_api, _CONCAT(&__sensor_read_config_, name))
     678              : 
     679              : /**
     680              :  * @brief Define a stream instance of a sensor
     681              :  *
     682              :  * Use this macro to generate a @ref rtio_iodev for starting a stream that's triggered by specific
     683              :  * interrupts. Example:
     684              :  *
     685              :  * @code(.c)
     686              :  * SENSOR_DT_STREAM_IODEV(imu_stream, DT_ALIAS(imu),
     687              :  *     {SENSOR_TRIG_FIFO_WATERMARK, SENSOR_STREAM_DATA_INCLUDE},
     688              :  *     {SENSOR_TRIG_FIFO_FULL, SENSOR_STREAM_DATA_NOP});
     689              :  *
     690              :  * int main(void) {
     691              :  *   struct rtio_sqe *handle;
     692              :  *   sensor_stream(&imu_stream, &rtio, NULL, &handle);
     693              :  *   k_msleep(1000);
     694              :  *   rtio_sqe_cancel(handle);
     695              :  * }
     696              :  * @endcode
     697              :  */
     698            1 : #define SENSOR_DT_STREAM_IODEV(name, dt_node, ...)                                                 \
     699              :         static struct sensor_stream_trigger _CONCAT(__trigger_array_, name)[] = {__VA_ARGS__};     \
     700              :         static struct sensor_read_config _CONCAT(__sensor_read_config_, name) = {                  \
     701              :                 .sensor = DEVICE_DT_GET(dt_node),                                                  \
     702              :                 .is_streaming = true,                                                              \
     703              :                 .triggers = _CONCAT(__trigger_array_, name),                                       \
     704              :                 .count = ARRAY_SIZE(_CONCAT(__trigger_array_, name)),                              \
     705              :                 .max = ARRAY_SIZE(_CONCAT(__trigger_array_, name)),                                \
     706              :         };                                                                                         \
     707              :         RTIO_IODEV_DEFINE(name, &__sensor_iodev_api, &_CONCAT(__sensor_read_config_, name))
     708              : 
     709              : /* Used to submit an RTIO sqe to the sensor's iodev */
     710            0 : typedef void (*sensor_submit_t)(const struct device *sensor, struct rtio_iodev_sqe *sqe);
     711              : 
     712              : /* The default decoder API */
     713              : extern const struct sensor_decoder_api __sensor_default_decoder;
     714              : 
     715              : /* The default sensor iodev API */
     716              : extern const struct rtio_iodev_api __sensor_iodev_api;
     717              : 
     718            0 : __subsystem struct sensor_driver_api {
     719            0 :         sensor_attr_set_t attr_set;
     720            0 :         sensor_attr_get_t attr_get;
     721            0 :         sensor_trigger_set_t trigger_set;
     722            0 :         sensor_sample_fetch_t sample_fetch;
     723            0 :         sensor_channel_get_t channel_get;
     724            0 :         sensor_get_decoder_t get_decoder;
     725            0 :         sensor_submit_t submit;
     726              : };
     727              : 
     728              : /**
     729              :  * @brief Set an attribute for a sensor
     730              :  *
     731              :  * @param dev Pointer to the sensor device
     732              :  * @param chan The channel the attribute belongs to, if any.  Some
     733              :  * attributes may only be set for all channels of a device, depending on
     734              :  * device capabilities.
     735              :  * @param attr The attribute to set
     736              :  * @param val The value to set the attribute to
     737              :  *
     738              :  * @return 0 if successful, negative errno code if failure.
     739              :  */
     740            1 : __syscall int sensor_attr_set(const struct device *dev,
     741              :                               enum sensor_channel chan,
     742              :                               enum sensor_attribute attr,
     743              :                               const struct sensor_value *val);
     744              : 
     745              : static inline int z_impl_sensor_attr_set(const struct device *dev,
     746              :                                          enum sensor_channel chan,
     747              :                                          enum sensor_attribute attr,
     748              :                                          const struct sensor_value *val)
     749              : {
     750              :         const struct sensor_driver_api *api =
     751              :                 (const struct sensor_driver_api *)dev->api;
     752              : 
     753              :         if (api->attr_set == NULL) {
     754              :                 return -ENOSYS;
     755              :         }
     756              : 
     757              :         return api->attr_set(dev, chan, attr, val);
     758              : }
     759              : 
     760              : /**
     761              :  * @brief Get an attribute for a sensor
     762              :  *
     763              :  * @param dev Pointer to the sensor device
     764              :  * @param chan The channel the attribute belongs to, if any.  Some
     765              :  * attributes may only be set for all channels of a device, depending on
     766              :  * device capabilities.
     767              :  * @param attr The attribute to get
     768              :  * @param val Pointer to where to store the attribute
     769              :  *
     770              :  * @return 0 if successful, negative errno code if failure.
     771              :  */
     772            1 : __syscall int sensor_attr_get(const struct device *dev,
     773              :                               enum sensor_channel chan,
     774              :                               enum sensor_attribute attr,
     775              :                               struct sensor_value *val);
     776              : 
     777              : static inline int z_impl_sensor_attr_get(const struct device *dev,
     778              :                                          enum sensor_channel chan,
     779              :                                          enum sensor_attribute attr,
     780              :                                          struct sensor_value *val)
     781              : {
     782              :         const struct sensor_driver_api *api =
     783              :                 (const struct sensor_driver_api *)dev->api;
     784              : 
     785              :         if (api->attr_get == NULL) {
     786              :                 return -ENOSYS;
     787              :         }
     788              : 
     789              :         return api->attr_get(dev, chan, attr, val);
     790              : }
     791              : 
     792              : /**
     793              :  * @brief Activate a sensor's trigger and set the trigger handler
     794              :  *
     795              :  * The handler will be called from a thread, so I2C or SPI operations are
     796              :  * safe.  However, the thread's stack is limited and defined by the
     797              :  * driver.  It is currently up to the caller to ensure that the handler
     798              :  * does not overflow the stack.
     799              :  *
     800              :  * The user-allocated trigger will be stored by the driver as a pointer, rather
     801              :  * than a copy, and passed back to the handler. This enables the handler to use
     802              :  * CONTAINER_OF to retrieve a context pointer when the trigger is embedded in a
     803              :  * larger struct and requires that the trigger is not allocated on the stack.
     804              :  *
     805              :  * @funcprops \supervisor
     806              :  *
     807              :  * @param dev Pointer to the sensor device
     808              :  * @param trig The trigger to activate
     809              :  * @param handler The function that should be called when the trigger
     810              :  * fires
     811              :  *
     812              :  * @return 0 if successful, negative errno code if failure.
     813              :  */
     814            1 : static inline int sensor_trigger_set(const struct device *dev,
     815              :                                      const struct sensor_trigger *trig,
     816              :                                      sensor_trigger_handler_t handler)
     817              : {
     818              :         const struct sensor_driver_api *api =
     819              :                 (const struct sensor_driver_api *)dev->api;
     820              : 
     821              :         if (api->trigger_set == NULL) {
     822              :                 return -ENOSYS;
     823              :         }
     824              : 
     825              :         return api->trigger_set(dev, trig, handler);
     826              : }
     827              : 
     828              : /**
     829              :  * @brief Fetch a sample from the sensor and store it in an internal
     830              :  * driver buffer
     831              :  *
     832              :  * Read all of a sensor's active channels and, if necessary, perform any
     833              :  * additional operations necessary to make the values useful.  The user
     834              :  * may then get individual channel values by calling @ref
     835              :  * sensor_channel_get.
     836              :  *
     837              :  * The function blocks until the fetch operation is complete.
     838              :  *
     839              :  * Since the function communicates with the sensor device, it is unsafe
     840              :  * to call it in an ISR if the device is connected via I2C or SPI.
     841              :  *
     842              :  * @param dev Pointer to the sensor device
     843              :  *
     844              :  * @return 0 if successful, negative errno code if failure.
     845              :  */
     846            1 : __syscall int sensor_sample_fetch(const struct device *dev);
     847              : 
     848              : static inline int z_impl_sensor_sample_fetch(const struct device *dev)
     849              : {
     850              :         const struct sensor_driver_api *api =
     851              :                 (const struct sensor_driver_api *)dev->api;
     852              : 
     853              :         return api->sample_fetch(dev, SENSOR_CHAN_ALL);
     854              : }
     855              : 
     856              : /**
     857              :  * @brief Fetch a sample from the sensor and store it in an internal
     858              :  * driver buffer
     859              :  *
     860              :  * Read and compute compensation for one type of sensor data (magnetometer,
     861              :  * accelerometer, etc). The user may then get individual channel values by
     862              :  * calling @ref sensor_channel_get.
     863              :  *
     864              :  * This is mostly implemented by multi function devices enabling reading at
     865              :  * different sampling rates.
     866              :  *
     867              :  * The function blocks until the fetch operation is complete.
     868              :  *
     869              :  * Since the function communicates with the sensor device, it is unsafe
     870              :  * to call it in an ISR if the device is connected via I2C or SPI.
     871              :  *
     872              :  * @param dev Pointer to the sensor device
     873              :  * @param type The channel that needs updated
     874              :  *
     875              :  * @return 0 if successful, negative errno code if failure.
     876              :  */
     877            1 : __syscall int sensor_sample_fetch_chan(const struct device *dev,
     878              :                                        enum sensor_channel type);
     879              : 
     880              : static inline int z_impl_sensor_sample_fetch_chan(const struct device *dev,
     881              :                                                   enum sensor_channel type)
     882              : {
     883              :         const struct sensor_driver_api *api =
     884              :                 (const struct sensor_driver_api *)dev->api;
     885              : 
     886              :         return api->sample_fetch(dev, type);
     887              : }
     888              : 
     889              : /**
     890              :  * @brief Get a reading from a sensor device
     891              :  *
     892              :  * Return a useful value for a particular channel, from the driver's
     893              :  * internal data.  Before calling this function, a sample must be
     894              :  * obtained by calling @ref sensor_sample_fetch or
     895              :  * @ref sensor_sample_fetch_chan. It is guaranteed that two subsequent
     896              :  * calls of this function for the same channels will yield the same
     897              :  * value, if @ref sensor_sample_fetch or @ref sensor_sample_fetch_chan
     898              :  * has not been called in the meantime.
     899              :  *
     900              :  * For vectorial data samples you can request all axes in just one call
     901              :  * by passing the specific channel with _XYZ suffix. The sample will be
     902              :  * returned at val[0], val[1] and val[2] (X, Y and Z in that order).
     903              :  *
     904              :  * @param dev Pointer to the sensor device
     905              :  * @param chan The channel to read
     906              :  * @param val Where to store the value
     907              :  *
     908              :  * @return 0 if successful, negative errno code if failure.
     909              :  */
     910            1 : __syscall int sensor_channel_get(const struct device *dev,
     911              :                                  enum sensor_channel chan,
     912              :                                  struct sensor_value *val);
     913              : 
     914              : static inline int z_impl_sensor_channel_get(const struct device *dev,
     915              :                                             enum sensor_channel chan,
     916              :                                             struct sensor_value *val)
     917              : {
     918              :         const struct sensor_driver_api *api =
     919              :                 (const struct sensor_driver_api *)dev->api;
     920              : 
     921              :         return api->channel_get(dev, chan, val);
     922              : }
     923              : 
     924              : #if defined(CONFIG_SENSOR_ASYNC_API) || defined(__DOXYGEN__)
     925              : 
     926              : /*
     927              :  * Generic data structure used for encoding the sample timestamp and number of channels sampled.
     928              :  */
     929            0 : struct __attribute__((__packed__)) sensor_data_generic_header {
     930              :         /* The timestamp at which the data was collected from the sensor */
     931            0 :         uint64_t timestamp_ns;
     932              : 
     933              :         /*
     934              :          * The number of channels present in the frame. This will be the true number of elements in
     935              :          * channel_info and in the q31 values that follow the header.
     936              :          */
     937            0 :         uint32_t num_channels;
     938              : 
     939              :         /* Shift value for all samples in the frame */
     940            0 :         int8_t shift;
     941              : 
     942              :         /* This padding is needed to make sure that the 'channels' field is aligned */
     943              :         int8_t _padding[sizeof(struct sensor_chan_spec) - 1];
     944              : 
     945              :         /* Channels present in the frame */
     946            0 :         struct sensor_chan_spec channels[0];
     947              : };
     948              : 
     949              : /**
     950              :  * @brief checks if a given channel is a 3-axis channel
     951              :  *
     952              :  * @param[in] chan The channel to check
     953              :  * @retval true if @p chan is any of @ref SENSOR_CHAN_ACCEL_XYZ, @ref SENSOR_CHAN_GYRO_XYZ, or
     954              :  *         @ref SENSOR_CHAN_MAGN_XYZ, or @ref SENSOR_CHAN_POS_DXYZ
     955              :  * @retval false otherwise
     956              :  */
     957            1 : #define SENSOR_CHANNEL_3_AXIS(chan)                                                                \
     958              :         ((chan) == SENSOR_CHAN_ACCEL_XYZ || (chan) == SENSOR_CHAN_GYRO_XYZ ||                      \
     959              :          (chan) == SENSOR_CHAN_MAGN_XYZ || (chan) == SENSOR_CHAN_POS_DXYZ)
     960              : 
     961              : /**
     962              :  * @brief checks if a given channel is an Accelerometer
     963              :  *
     964              :  * @param[in] chan The channel to check
     965              :  * @retval true if @p chan is any of @ref SENSOR_CHAN_ACCEL_XYZ, @ref SENSOR_CHAN_ACCEL_X, or
     966              :  *         @ref SENSOR_CHAN_ACCEL_Y, or @ref SENSOR_CHAN_ACCEL_Z
     967              :  * @retval false otherwise
     968              :  */
     969            1 : #define SENSOR_CHANNEL_IS_ACCEL(chan)                                          \
     970              :         ((chan) == SENSOR_CHAN_ACCEL_XYZ || (chan) == SENSOR_CHAN_ACCEL_X ||   \
     971              :          (chan) == SENSOR_CHAN_ACCEL_Y || (chan) == SENSOR_CHAN_ACCEL_Z)
     972              : 
     973              : /**
     974              :  * @brief checks if a given channel is a Gyroscope
     975              :  *
     976              :  * @param[in] chan The channel to check
     977              :  * @retval true if @p chan is any of @ref SENSOR_CHAN_GYRO_XYZ, @ref SENSOR_CHAN_GYRO_X, or
     978              :  *         @ref SENSOR_CHAN_GYRO_Y, or @ref SENSOR_CHAN_GYRO_Z
     979              :  * @retval false otherwise
     980              :  */
     981            1 : #define SENSOR_CHANNEL_IS_GYRO(chan)                                           \
     982              :         ((chan) == SENSOR_CHAN_GYRO_XYZ || (chan) == SENSOR_CHAN_GYRO_X ||     \
     983              :          (chan) == SENSOR_CHAN_GYRO_Y || (chan) == SENSOR_CHAN_GYRO_Z)
     984              : 
     985              : /**
     986              :  * @brief Get the sensor's decoder API
     987              :  *
     988              :  * @param[in] dev The sensor device
     989              :  * @param[in] decoder Pointer to the decoder which will be set upon success
     990              :  * @return 0 on success
     991              :  * @return < 0 on error
     992              :  */
     993            1 : __syscall int sensor_get_decoder(const struct device *dev,
     994              :                                  const struct sensor_decoder_api **decoder);
     995              : 
     996              : static inline int z_impl_sensor_get_decoder(const struct device *dev,
     997              :                                             const struct sensor_decoder_api **decoder)
     998              : {
     999              :         const struct sensor_driver_api *api = (const struct sensor_driver_api *)dev->api;
    1000              : 
    1001              :         __ASSERT_NO_MSG(api != NULL);
    1002              : 
    1003              :         if (api->get_decoder == NULL) {
    1004              :                 *decoder = &__sensor_default_decoder;
    1005              :                 return 0;
    1006              :         }
    1007              : 
    1008              :         return api->get_decoder(dev, decoder);
    1009              : }
    1010              : 
    1011              : /**
    1012              :  * @brief Reconfigure a reading iodev
    1013              :  *
    1014              :  * Allows a reconfiguration of the iodev associated with reading a sample from a sensor.
    1015              :  *
    1016              :  * <b>Important</b>: If the iodev is currently servicing a read operation, the data will likely be
    1017              :  * invalid. Please be sure the flush or wait for all pending operations to complete before using the
    1018              :  * data after a configuration change.
    1019              :  *
    1020              :  * It is also important that the `data` field of the iodev is a @ref sensor_read_config.
    1021              :  *
    1022              :  * @param[in] iodev The iodev to reconfigure
    1023              :  * @param[in] sensor The sensor to read from
    1024              :  * @param[in] channels One or more channels to read
    1025              :  * @param[in] num_channels The number of channels in @p channels
    1026              :  * @return 0 on success
    1027              :  * @return < 0 on error
    1028              :  */
    1029            1 : __syscall int sensor_reconfigure_read_iodev(struct rtio_iodev *iodev, const struct device *sensor,
    1030              :                                             const struct sensor_chan_spec *channels,
    1031              :                                             size_t num_channels);
    1032              : 
    1033              : static inline int z_impl_sensor_reconfigure_read_iodev(struct rtio_iodev *iodev,
    1034              :                                                        const struct device *sensor,
    1035              :                                                        const struct sensor_chan_spec *channels,
    1036              :                                                        size_t num_channels)
    1037              : {
    1038              :         struct sensor_read_config *cfg = (struct sensor_read_config *)iodev->data;
    1039              : 
    1040              :         if (cfg->max < num_channels || cfg->is_streaming) {
    1041              :                 return -ENOMEM;
    1042              :         }
    1043              : 
    1044              :         cfg->sensor = sensor;
    1045              :         memcpy(cfg->channels, channels, num_channels * sizeof(struct sensor_chan_spec));
    1046              :         cfg->count = num_channels;
    1047              :         return 0;
    1048              : }
    1049              : 
    1050            0 : static inline int sensor_stream(struct rtio_iodev *iodev, struct rtio *ctx, void *userdata,
    1051              :                                 struct rtio_sqe **handle)
    1052              : {
    1053              :         if (IS_ENABLED(CONFIG_USERSPACE)) {
    1054              :                 struct rtio_sqe sqe;
    1055              : 
    1056              :                 rtio_sqe_prep_read_multishot(&sqe, iodev, RTIO_PRIO_NORM, userdata);
    1057              :                 rtio_sqe_copy_in_get_handles(ctx, &sqe, handle, 1);
    1058              :         } else {
    1059              :                 struct rtio_sqe *sqe = rtio_sqe_acquire(ctx);
    1060              : 
    1061              :                 if (sqe == NULL) {
    1062              :                         return -ENOMEM;
    1063              :                 }
    1064              :                 if (handle != NULL) {
    1065              :                         *handle = sqe;
    1066              :                 }
    1067              :                 rtio_sqe_prep_read_multishot(sqe, iodev, RTIO_PRIO_NORM, userdata);
    1068              :         }
    1069              :         rtio_submit(ctx, 0);
    1070              :         return 0;
    1071              : }
    1072              : 
    1073              : /**
    1074              :  * @brief Blocking one shot read of samples from a sensor into a buffer
    1075              :  *
    1076              :  * Using @p cfg, read data from the device by using the provided RTIO context
    1077              :  * @p ctx. This call will generate a @ref rtio_sqe that will be given the provided buffer. The call
    1078              :  * will wait for the read to complete before returning to the caller.
    1079              :  *
    1080              :  * @param[in] iodev The iodev created by @ref SENSOR_DT_READ_IODEV
    1081              :  * @param[in] ctx The RTIO context to service the read
    1082              :  * @param[in] buf Pointer to memory to read sample data into
    1083              :  * @param[in] buf_len Size in bytes of the given memory that are valid to read into
    1084              :  * @return 0 on success
    1085              :  * @return < 0 on error
    1086              :  */
    1087            1 : static inline int sensor_read(struct rtio_iodev *iodev, struct rtio *ctx, uint8_t *buf,
    1088              :                               size_t buf_len)
    1089              : {
    1090              :         if (IS_ENABLED(CONFIG_USERSPACE)) {
    1091              :                 struct rtio_sqe sqe;
    1092              : 
    1093              :                 rtio_sqe_prep_read(&sqe, iodev, RTIO_PRIO_NORM, buf, buf_len, buf);
    1094              :                 rtio_sqe_copy_in(ctx, &sqe, 1);
    1095              :         } else {
    1096              :                 struct rtio_sqe *sqe = rtio_sqe_acquire(ctx);
    1097              : 
    1098              :                 if (sqe == NULL) {
    1099              :                         return -ENOMEM;
    1100              :                 }
    1101              :                 rtio_sqe_prep_read(sqe, iodev, RTIO_PRIO_NORM, buf, buf_len, buf);
    1102              :         }
    1103              :         rtio_submit(ctx, 0);
    1104              : 
    1105              :         struct rtio_cqe *cqe = rtio_cqe_consume_block(ctx);
    1106              :         int res = cqe->result;
    1107              : 
    1108              :         __ASSERT(cqe->userdata == buf,
    1109              :                  "consumed non-matching completion for sensor read into buffer %p\n", buf);
    1110              : 
    1111              :         rtio_cqe_release(ctx, cqe);
    1112              : 
    1113              :         return res;
    1114              : }
    1115              : 
    1116              : /**
    1117              :  * @brief One shot non-blocking read with pool allocated buffer
    1118              :  *
    1119              :  * Using @p cfg, read one snapshot of data from the device by using the provided RTIO context
    1120              :  * @p ctx. This call will generate a @ref rtio_sqe that will leverage the RTIO's internal
    1121              :  * mempool when the time comes to service the read.
    1122              :  *
    1123              :  * @param[in] iodev The iodev created by @ref SENSOR_DT_READ_IODEV
    1124              :  * @param[in] ctx The RTIO context to service the read
    1125              :  * @param[in] userdata Optional userdata that will be available when the read is complete
    1126              :  * @return 0 on success
    1127              :  * @return < 0 on error
    1128              :  */
    1129            1 : static inline int sensor_read_async_mempool(struct rtio_iodev *iodev, struct rtio *ctx,
    1130              :                                             void *userdata)
    1131              : {
    1132              :         if (IS_ENABLED(CONFIG_USERSPACE)) {
    1133              :                 struct rtio_sqe sqe;
    1134              : 
    1135              :                 rtio_sqe_prep_read_with_pool(&sqe, iodev, RTIO_PRIO_NORM, userdata);
    1136              :                 rtio_sqe_copy_in(ctx, &sqe, 1);
    1137              :         } else {
    1138              :                 struct rtio_sqe *sqe = rtio_sqe_acquire(ctx);
    1139              : 
    1140              :                 if (sqe == NULL) {
    1141              :                         return -ENOMEM;
    1142              :                 }
    1143              :                 rtio_sqe_prep_read_with_pool(sqe, iodev, RTIO_PRIO_NORM, userdata);
    1144              :         }
    1145              :         rtio_submit(ctx, 0);
    1146              :         return 0;
    1147              : }
    1148              : 
    1149              : /**
    1150              :  * @typedef sensor_processing_callback_t
    1151              :  * @brief Callback function used with the helper processing function.
    1152              :  *
    1153              :  * @see sensor_processing_with_callback
    1154              :  *
    1155              :  * @param[in] result The result code of the read (0 being success)
    1156              :  * @param[in] buf The data buffer holding the sensor data
    1157              :  * @param[in] buf_len The length (in bytes) of the @p buf
    1158              :  * @param[in] userdata The optional userdata passed to sensor_read_async_mempool()
    1159              :  */
    1160            1 : typedef void (*sensor_processing_callback_t)(int result, uint8_t *buf, uint32_t buf_len,
    1161              :                                              void *userdata);
    1162              : 
    1163              : /**
    1164              :  * @brief Helper function for common processing of sensor data.
    1165              :  *
    1166              :  * This function can be called in a blocking manner after sensor_read() or in a standalone
    1167              :  * thread dedicated to processing. It will wait for a cqe from the RTIO context, once received, it
    1168              :  * will decode the userdata and call the @p cb. Once the @p cb returns, the buffer will be released
    1169              :  * back into @p ctx's mempool if available.
    1170              :  *
    1171              :  * @param[in] ctx The RTIO context to wait on
    1172              :  * @param[in] cb Callback to call when data is ready for processing
    1173              :  */
    1174            1 : void sensor_processing_with_callback(struct rtio *ctx, sensor_processing_callback_t cb);
    1175              : 
    1176              : #endif /* defined(CONFIG_SENSOR_ASYNC_API) || defined(__DOXYGEN__) */
    1177              : 
    1178              : /**
    1179              :  * @brief The value of gravitational constant in micro m/s^2.
    1180              :  */
    1181            1 : #define SENSOR_G                9806650LL
    1182              : 
    1183              : /**
    1184              :  * @brief The value of constant PI in micros.
    1185              :  */
    1186            1 : #define SENSOR_PI               3141592LL
    1187              : 
    1188              : /**
    1189              :  * @brief Helper function to convert acceleration from m/s^2 to Gs
    1190              :  *
    1191              :  * @param ms2 A pointer to a sensor_value struct holding the acceleration,
    1192              :  *            in m/s^2.
    1193              :  *
    1194              :  * @return The converted value, in Gs.
    1195              :  */
    1196            1 : static inline int32_t sensor_ms2_to_g(const struct sensor_value *ms2)
    1197              : {
    1198              :         int64_t micro_ms2 = ms2->val1 * 1000000LL + ms2->val2;
    1199              : 
    1200              :         if (micro_ms2 > 0) {
    1201              :                 return (micro_ms2 + SENSOR_G / 2) / SENSOR_G;
    1202              :         } else {
    1203              :                 return (micro_ms2 - SENSOR_G / 2) / SENSOR_G;
    1204              :         }
    1205              : }
    1206              : 
    1207              : /**
    1208              :  * @brief Helper function to convert acceleration from Gs to m/s^2
    1209              :  *
    1210              :  * @param g The G value to be converted.
    1211              :  * @param ms2 A pointer to a sensor_value struct, where the result is stored.
    1212              :  */
    1213            1 : static inline void sensor_g_to_ms2(int32_t g, struct sensor_value *ms2)
    1214              : {
    1215              :         ms2->val1 = ((int64_t)g * SENSOR_G) / 1000000LL;
    1216              :         ms2->val2 = ((int64_t)g * SENSOR_G) % 1000000LL;
    1217              : }
    1218              : 
    1219              : /**
    1220              :  * @brief Helper function to convert acceleration from m/s^2 to milli Gs
    1221              :  *
    1222              :  * @param ms2 A pointer to a sensor_value struct holding the acceleration,
    1223              :  *            in m/s^2.
    1224              :  *
    1225              :  * @return The converted value, in milli Gs.
    1226              :  */
    1227            1 : static inline int32_t sensor_ms2_to_mg(const struct sensor_value *ms2)
    1228              : {
    1229              :         int64_t nano_ms2 = (ms2->val1 * 1000000LL + ms2->val2) * 1000LL;
    1230              : 
    1231              :         if (nano_ms2 > 0) {
    1232              :                 return (nano_ms2 + SENSOR_G / 2) / SENSOR_G;
    1233              :         } else {
    1234              :                 return (nano_ms2 - SENSOR_G / 2) / SENSOR_G;
    1235              :         }
    1236              : }
    1237              : 
    1238              : /**
    1239              :  * @brief Helper function to convert acceleration from m/s^2 to micro Gs
    1240              :  *
    1241              :  * @param ms2 A pointer to a sensor_value struct holding the acceleration,
    1242              :  *            in m/s^2.
    1243              :  *
    1244              :  * @return The converted value, in micro Gs.
    1245              :  */
    1246            1 : static inline int32_t sensor_ms2_to_ug(const struct sensor_value *ms2)
    1247              : {
    1248              :         int64_t micro_ms2 = (ms2->val1 * INT64_C(1000000)) + ms2->val2;
    1249              : 
    1250              :         return (micro_ms2 * 1000000LL) / SENSOR_G;
    1251              : }
    1252              : 
    1253              : /**
    1254              :  * @brief Helper function to convert acceleration from micro Gs to m/s^2
    1255              :  *
    1256              :  * @param ug The micro G value to be converted.
    1257              :  * @param ms2 A pointer to a sensor_value struct, where the result is stored.
    1258              :  */
    1259            1 : static inline void sensor_ug_to_ms2(int32_t ug, struct sensor_value *ms2)
    1260              : {
    1261              :         ms2->val1 = ((int64_t)ug * SENSOR_G / 1000000LL) / 1000000LL;
    1262              :         ms2->val2 = ((int64_t)ug * SENSOR_G / 1000000LL) % 1000000LL;
    1263              : }
    1264              : 
    1265              : /**
    1266              :  * @brief Helper function for converting radians to degrees.
    1267              :  *
    1268              :  * @param rad A pointer to a sensor_value struct, holding the value in radians.
    1269              :  *
    1270              :  * @return The converted value, in degrees.
    1271              :  */
    1272            1 : static inline int32_t sensor_rad_to_degrees(const struct sensor_value *rad)
    1273              : {
    1274              :         int64_t micro_rad_s = rad->val1 * 1000000LL + rad->val2;
    1275              : 
    1276              :         if (micro_rad_s > 0) {
    1277              :                 return (micro_rad_s * 180LL + SENSOR_PI / 2) / SENSOR_PI;
    1278              :         } else {
    1279              :                 return (micro_rad_s * 180LL - SENSOR_PI / 2) / SENSOR_PI;
    1280              :         }
    1281              : }
    1282              : 
    1283              : /**
    1284              :  * @brief Helper function for converting degrees to radians.
    1285              :  *
    1286              :  * @param d The value (in degrees) to be converted.
    1287              :  * @param rad A pointer to a sensor_value struct, where the result is stored.
    1288              :  */
    1289            1 : static inline void sensor_degrees_to_rad(int32_t d, struct sensor_value *rad)
    1290              : {
    1291              :         rad->val1 = ((int64_t)d * SENSOR_PI / 180LL) / 1000000LL;
    1292              :         rad->val2 = ((int64_t)d * SENSOR_PI / 180LL) % 1000000LL;
    1293              : }
    1294              : 
    1295              : /**
    1296              :  * @brief Helper function for converting radians to 10 micro degrees.
    1297              :  *
    1298              :  * When the unit is 1 micro degree, the range that the int32_t can represent is
    1299              :  * +/-2147.483 degrees. In order to increase this range, here we use 10 micro
    1300              :  * degrees as the unit.
    1301              :  *
    1302              :  * @param rad A pointer to a sensor_value struct, holding the value in radians.
    1303              :  *
    1304              :  * @return The converted value, in 10 micro degrees.
    1305              :  */
    1306            1 : static inline int32_t sensor_rad_to_10udegrees(const struct sensor_value *rad)
    1307              : {
    1308              :         int64_t micro_rad_s = rad->val1 * 1000000LL + rad->val2;
    1309              : 
    1310              :         return (micro_rad_s * 180LL * 100000LL) / SENSOR_PI;
    1311              : }
    1312              : 
    1313              : /**
    1314              :  * @brief Helper function for converting 10 micro degrees to radians.
    1315              :  *
    1316              :  * @param d The value (in 10 micro degrees) to be converted.
    1317              :  * @param rad A pointer to a sensor_value struct, where the result is stored.
    1318              :  */
    1319            1 : static inline void sensor_10udegrees_to_rad(int32_t d, struct sensor_value *rad)
    1320              : {
    1321              :         rad->val1 = ((int64_t)d * SENSOR_PI / 180LL / 100000LL) / 1000000LL;
    1322              :         rad->val2 = ((int64_t)d * SENSOR_PI / 180LL / 100000LL) % 1000000LL;
    1323              : }
    1324              : 
    1325              : /**
    1326              :  * @brief Helper function for converting struct sensor_value to double.
    1327              :  *
    1328              :  * @param val A pointer to a sensor_value struct.
    1329              :  * @return The converted value.
    1330              :  */
    1331            1 : static inline double sensor_value_to_double(const struct sensor_value *val)
    1332              : {
    1333              :         return (double)val->val1 + (double)val->val2 / 1000000;
    1334              : }
    1335              : 
    1336              : /**
    1337              :  * @brief Helper function for converting struct sensor_value to float.
    1338              :  *
    1339              :  * @param val A pointer to a sensor_value struct.
    1340              :  * @return The converted value.
    1341              :  */
    1342            1 : static inline float sensor_value_to_float(const struct sensor_value *val)
    1343              : {
    1344              :         return (float)val->val1 + (float)val->val2 / 1000000;
    1345              : }
    1346              : 
    1347              : /**
    1348              :  * @brief Helper function for converting double to struct sensor_value.
    1349              :  *
    1350              :  * @param val A pointer to a sensor_value struct.
    1351              :  * @param inp The converted value.
    1352              :  * @return 0 if successful, negative errno code if failure.
    1353              :  */
    1354            1 : static inline int sensor_value_from_double(struct sensor_value *val, double inp)
    1355              : {
    1356              :         if (inp < (double)INT32_MIN || inp > (double)INT32_MAX) {
    1357              :                 return -ERANGE;
    1358              :         }
    1359              : 
    1360              :         int32_t val1 = (int32_t)inp;
    1361              :         int32_t val2 = (int32_t)((inp - (double)val1) * 1000000.0);
    1362              : 
    1363              :         val->val1 = val1;
    1364              :         val->val2 = val2;
    1365              : 
    1366              :         return 0;
    1367              : }
    1368              : 
    1369              : /**
    1370              :  * @brief Helper function for converting float to struct sensor_value.
    1371              :  *
    1372              :  * @param val A pointer to a sensor_value struct.
    1373              :  * @param inp The converted value.
    1374              :  * @return 0 if successful, negative errno code if failure.
    1375              :  */
    1376            1 : static inline int sensor_value_from_float(struct sensor_value *val, float inp)
    1377              : {
    1378              :         if (inp < (float)INT32_MIN || inp >= (float)INT32_MAX) {
    1379              :                 return -ERANGE;
    1380              :         }
    1381              : 
    1382              :         int32_t val1 = (int32_t)inp;
    1383              :         int32_t val2 = (int32_t)((inp - (float)val1) * 1000000.0f);
    1384              : 
    1385              :         val->val1 = val1;
    1386              :         val->val2 = val2;
    1387              : 
    1388              :         return 0;
    1389              : }
    1390              : 
    1391              : #ifdef CONFIG_SENSOR_INFO
    1392              : 
    1393              : struct sensor_info {
    1394              :         const struct device *dev;
    1395              :         const char *vendor;
    1396              :         const char *model;
    1397              :         const char *friendly_name;
    1398              : };
    1399              : 
    1400              : #define SENSOR_INFO_INITIALIZER(_dev, _vendor, _model, _friendly_name)  \
    1401              :         {                                                               \
    1402              :                 .dev = _dev,                                            \
    1403              :                 .vendor = _vendor,                                      \
    1404              :                 .model = _model,                                        \
    1405              :                 .friendly_name = _friendly_name,                        \
    1406              :         }
    1407              : 
    1408              : #define SENSOR_INFO_DEFINE(name, ...)                                   \
    1409              :         static const STRUCT_SECTION_ITERABLE(sensor_info, name) =       \
    1410              :                 SENSOR_INFO_INITIALIZER(__VA_ARGS__)
    1411              : 
    1412              : #define SENSOR_INFO_DT_NAME(node_id)                                    \
    1413              :         _CONCAT(__sensor_info, DEVICE_DT_NAME_GET(node_id))
    1414              : 
    1415              : #define SENSOR_INFO_DT_DEFINE(node_id)                                  \
    1416              :         SENSOR_INFO_DEFINE(SENSOR_INFO_DT_NAME(node_id),                \
    1417              :                            DEVICE_DT_GET(node_id),                      \
    1418              :                            DT_NODE_VENDOR_OR(node_id, NULL),            \
    1419              :                            DT_NODE_MODEL_OR(node_id, NULL),             \
    1420              :                            DT_PROP_OR(node_id, friendly_name, NULL))    \
    1421              : 
    1422              : #else
    1423              : 
    1424            0 : #define SENSOR_INFO_DEFINE(name, ...)
    1425            0 : #define SENSOR_INFO_DT_DEFINE(node_id)
    1426              : 
    1427              : #endif /* CONFIG_SENSOR_INFO */
    1428              : 
    1429              : /**
    1430              :  * @brief Like DEVICE_DT_DEFINE() with sensor specifics.
    1431              :  *
    1432              :  * @details Defines a device which implements the sensor API. May define an
    1433              :  * element in the sensor info iterable section used to enumerate all sensor
    1434              :  * devices.
    1435              :  *
    1436              :  * @param node_id The devicetree node identifier.
    1437              :  *
    1438              :  * @param init_fn Name of the init function of the driver.
    1439              :  *
    1440              :  * @param pm_device PM device resources reference (NULL if device does not use
    1441              :  * PM).
    1442              :  *
    1443              :  * @param data_ptr Pointer to the device's private data.
    1444              :  *
    1445              :  * @param cfg_ptr The address to the structure containing the configuration
    1446              :  * information for this instance of the driver.
    1447              :  *
    1448              :  * @param level The initialization level. See SYS_INIT() for details.
    1449              :  *
    1450              :  * @param prio Priority within the selected initialization level. See
    1451              :  * SYS_INIT() for details.
    1452              :  *
    1453              :  * @param api_ptr Provides an initial pointer to the API function struct used
    1454              :  * by the driver. Can be NULL.
    1455              :  */
    1456              : #define SENSOR_DEVICE_DT_DEFINE(node_id, init_fn, pm_device,            \
    1457              :                                 data_ptr, cfg_ptr, level, prio,         \
    1458            1 :                                 api_ptr, ...)                           \
    1459              :         DEVICE_DT_DEFINE(node_id, init_fn, pm_device,                   \
    1460              :                          data_ptr, cfg_ptr, level, prio,                \
    1461              :                          api_ptr, __VA_ARGS__);                         \
    1462              :                                                                         \
    1463              :         SENSOR_INFO_DT_DEFINE(node_id);
    1464              : 
    1465              : /**
    1466              :  * @brief Like SENSOR_DEVICE_DT_DEFINE() for an instance of a DT_DRV_COMPAT
    1467              :  * compatible
    1468              :  *
    1469              :  * @param inst instance number. This is replaced by
    1470              :  * <tt>DT_DRV_COMPAT(inst)</tt> in the call to SENSOR_DEVICE_DT_DEFINE().
    1471              :  *
    1472              :  * @param ... other parameters as expected by SENSOR_DEVICE_DT_DEFINE().
    1473              :  */
    1474            1 : #define SENSOR_DEVICE_DT_INST_DEFINE(inst, ...)                         \
    1475              :         SENSOR_DEVICE_DT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__)
    1476              : 
    1477              : /**
    1478              :  * @brief Helper function for converting struct sensor_value to integer deci units.
    1479              :  *
    1480              :  * @param val A pointer to a sensor_value struct.
    1481              :  * @return The converted value.
    1482              :  */
    1483            1 : static inline int64_t sensor_value_to_deci(const struct sensor_value *val)
    1484              : {
    1485              :         return ((int64_t)val->val1 * 10) + val->val2 / 100000;
    1486              : }
    1487              : 
    1488              : /**
    1489              :  * @brief Helper function for converting struct sensor_value to integer centi units.
    1490              :  *
    1491              :  * @param val A pointer to a sensor_value struct.
    1492              :  * @return The converted value.
    1493              :  */
    1494            1 : static inline int64_t sensor_value_to_centi(const struct sensor_value *val)
    1495              : {
    1496              :         return ((int64_t)val->val1 * 100) + val->val2 / 10000;
    1497              : }
    1498              : 
    1499              : /**
    1500              :  * @brief Helper function for converting struct sensor_value to integer milli units.
    1501              :  *
    1502              :  * @param val A pointer to a sensor_value struct.
    1503              :  * @return The converted value.
    1504              :  */
    1505            1 : static inline int64_t sensor_value_to_milli(const struct sensor_value *val)
    1506              : {
    1507              :         return ((int64_t)val->val1 * 1000) + val->val2 / 1000;
    1508              : }
    1509              : 
    1510              : /**
    1511              :  * @brief Helper function for converting struct sensor_value to integer micro units.
    1512              :  *
    1513              :  * @param val A pointer to a sensor_value struct.
    1514              :  * @return The converted value.
    1515              :  */
    1516            1 : static inline int64_t sensor_value_to_micro(const struct sensor_value *val)
    1517              : {
    1518              :         return ((int64_t)val->val1 * 1000000) + val->val2;
    1519              : }
    1520              : 
    1521              : /**
    1522              :  * @brief Helper function for converting integer milli units to struct sensor_value.
    1523              :  *
    1524              :  * @param val A pointer to a sensor_value struct.
    1525              :  * @param milli The converted value.
    1526              :  * @return 0 if successful, negative errno code if failure.
    1527              :  */
    1528            1 : static inline int sensor_value_from_milli(struct sensor_value *val, int64_t milli)
    1529              : {
    1530              :         if (milli < ((int64_t)INT32_MIN - 1) * 1000LL ||
    1531              :                         milli > ((int64_t)INT32_MAX + 1) * 1000LL) {
    1532              :                 return -ERANGE;
    1533              :         }
    1534              : 
    1535              :         val->val1 = (int32_t)(milli / 1000);
    1536              :         val->val2 = (int32_t)(milli % 1000) * 1000;
    1537              : 
    1538              :         return 0;
    1539              : }
    1540              : 
    1541              : /**
    1542              :  * @brief Helper function for converting integer micro units to struct sensor_value.
    1543              :  *
    1544              :  * @param val A pointer to a sensor_value struct.
    1545              :  * @param micro The converted value.
    1546              :  * @return 0 if successful, negative errno code if failure.
    1547              :  */
    1548            1 : static inline int sensor_value_from_micro(struct sensor_value *val, int64_t micro)
    1549              : {
    1550              :         if (micro < ((int64_t)INT32_MIN - 1) * 1000000LL ||
    1551              :                         micro > ((int64_t)INT32_MAX + 1) * 1000000LL) {
    1552              :                 return -ERANGE;
    1553              :         }
    1554              : 
    1555              :         val->val1 = (int32_t)(micro / 1000000LL);
    1556              :         val->val2 = (int32_t)(micro % 1000000LL);
    1557              : 
    1558              :         return 0;
    1559              : }
    1560              : 
    1561              : /**
    1562              :  * @}
    1563              :  */
    1564              : 
    1565              : /**
    1566              :  * @brief Get the decoder name for the current driver
    1567              :  *
    1568              :  * This function depends on `DT_DRV_COMPAT` being defined.
    1569              :  */
    1570            1 : #define SENSOR_DECODER_NAME() UTIL_CAT(DT_DRV_COMPAT, __decoder_api)
    1571              : 
    1572              : /**
    1573              :  * @brief Statically get the decoder for a given node
    1574              :  *
    1575              :  * @code{.c}
    1576              :  * static const sensor_decoder_api *decoder = SENSOR_DECODER_DT_GET(DT_ALIAS(accel));
    1577              :  * @endcode
    1578              :  */
    1579            1 : #define SENSOR_DECODER_DT_GET(node_id)                                                             \
    1580              :         &UTIL_CAT(DT_STRING_TOKEN_BY_IDX(node_id, compatible, 0), __decoder_api)
    1581              : 
    1582              : /**
    1583              :  * @brief Define a decoder API
    1584              :  *
    1585              :  * This macro should be created once per compatible string of a sensor and will create a statically
    1586              :  * referenceable decoder API.
    1587              :  *
    1588              :  * @code{.c}
    1589              :  * SENSOR_DECODER_API_DT_DEFINE() = {
    1590              :  *   .get_frame_count = my_driver_get_frame_count,
    1591              :  *   .get_timestamp = my_driver_get_timestamp,
    1592              :  *   .get_shift = my_driver_get_shift,
    1593              :  *   .decode = my_driver_decode,
    1594              :  * };
    1595              :  * @endcode
    1596              :  */
    1597            1 : #define SENSOR_DECODER_API_DT_DEFINE()                                                             \
    1598              :         COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT), (), (static))                        \
    1599              :         const STRUCT_SECTION_ITERABLE(sensor_decoder_api, SENSOR_DECODER_NAME())
    1600              : 
    1601              : #define Z_MAYBE_SENSOR_DECODER_DECLARE_INTERNAL_IDX(node_id, prop, idx)                            \
    1602              :         extern const struct sensor_decoder_api UTIL_CAT(                                           \
    1603              :                 DT_STRING_TOKEN_BY_IDX(node_id, prop, idx), __decoder_api);
    1604              : 
    1605              : #define Z_MAYBE_SENSOR_DECODER_DECLARE_INTERNAL(node_id)                                           \
    1606              :         COND_CODE_1(DT_NODE_HAS_PROP(node_id, compatible),                                         \
    1607              :                     (DT_FOREACH_PROP_ELEM(node_id, compatible,                                     \
    1608              :                                           Z_MAYBE_SENSOR_DECODER_DECLARE_INTERNAL_IDX)),           \
    1609              :                     ())
    1610              : 
    1611              : DT_FOREACH_STATUS_OKAY_NODE(Z_MAYBE_SENSOR_DECODER_DECLARE_INTERNAL)
    1612              : 
    1613              : #ifdef __cplusplus
    1614              : }
    1615              : #endif
    1616              : 
    1617              : #include <zephyr/syscalls/sensor.h>
    1618              : 
    1619              : #endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_H_ */
        

Generated by: LCOV version 2.0-1