LCOV - code coverage report
Current view: top level - zephyr/drivers - sensor.h Coverage Total Hit
Test: new.info Lines: 70.1 % 107 75
Test Date: 2025-10-20 06:18:59

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

Generated by: LCOV version 2.0-1