1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #ifndef MOD_SENSOR_H
9 #define MOD_SENSOR_H
10 
11 #include <fwk_id.h>
12 #include <fwk_module_idx.h>
13 
14 #include <stdbool.h>
15 #include <stdint.h>
16 
17 /*!
18  * \addtogroup GroupModules Modules
19  * \{
20  */
21 
22 /*!
23  * \defgroup GroupModuleSensor Sensor
24  *
25  * \brief Module for reading hardware sensors.
26  *
27  * \details Module for interfacing with and reading various hardware sensors.
28  *
29  * \{
30  */
31 
32 /*!
33  * \brief Sensor types as defined by SCMI.
34  */
35 enum mod_sensor_type {
36     MOD_SENSOR_TYPE_NONE = 0,
37     MOD_SENSOR_TYPE_UNSPECIFIED,
38     MOD_SENSOR_TYPE_DEGREES_C,
39     MOD_SENSOR_TYPE_DEGREES_F,
40     MOD_SENSOR_TYPE_DEGREES_K,
41     MOD_SENSOR_TYPE_VOLTS,
42     MOD_SENSOR_TYPE_AMPS,
43     MOD_SENSOR_TYPE_WATTS,
44     MOD_SENSOR_TYPE_JOULES,
45     MOD_SENSOR_TYPE_COULOMBS,
46     MOD_SENSOR_TYPE_VA,
47     MOD_SENSOR_TYPE_NITS,
48     MOD_SENSOR_TYPE_LUMENS,
49     MOD_SENSOR_TYPE_LUX,
50     MOD_SENSOR_TYPE_CANDELAS,
51     MOD_SENSOR_TYPE_KPA,
52     MOD_SENSOR_TYPE_PSI,
53     MOD_SENSOR_TYPE_NEWTONS,
54     MOD_SENSOR_TYPE_CFM,
55     MOD_SENSOR_TYPE_RPM,
56     MOD_SENSOR_TYPE_HERTZ,
57     MOD_SENSOR_TYPE_SECONDS,
58     MOD_SENSOR_TYPE_MINUTES,
59     MOD_SENSOR_TYPE_HOURS,
60     MOD_SENSOR_TYPE_DAYS,
61     MOD_SENSOR_TYPE_WEEKS,
62     MOD_SENSOR_TYPE_MILS,
63     MOD_SENSOR_TYPE_INCHES,
64     MOD_SENSOR_TYPE_FEET,
65     MOD_SENSOR_TYPE_CUBIC_INCHES,
66     MOD_SENSOR_TYPE_CUBIC_FEET,
67     MOD_SENSOR_TYPE_METERS,
68     MOD_SENSOR_TYPE_CUBIC_CENTIMETERS,
69     MOD_SENSOR_TYPE_CUBIC_METERS,
70     MOD_SENSOR_TYPE_LITRES,
71     MOD_SENSOR_TYPE_FLUID_OUNCES,
72     MOD_SENSOR_TYPE_RADIANS,
73     MOD_SENSOR_TYPE_STERADIANS,
74     MOD_SENSOR_TYPE_REVOLUTIONS,
75     MOD_SENSOR_TYPE_CYCLES,
76     MOD_SENSOR_TYPE_GRAVITIES,
77     MOD_SENSOR_TYPE_OUNCES,
78     MOD_SENSOR_TYPE_POUNDS,
79     MOD_SENSOR_TYPE_FOOT_POUNDS,
80     MOD_SENSOR_TYPE_OUNCE_INCHES,
81     MOD_SENSOR_TYPE_GAUSS,
82     MOD_SENSOR_TYPE_GILBERTS,
83     MOD_SENSOR_TYPE_HENRIES,
84     MOD_SENSOR_TYPE_FARADS,
85     MOD_SENSOR_TYPE_OHMS,
86     MOD_SENSOR_TYPE_SIEMENS,
87     MOD_SENSOR_TYPE_MOLES,
88     MOD_SENSOR_TYPE_BECQUERELS,
89     MOD_SENSOR_TYPE_PPM,
90     MOD_SENSOR_TYPE_DECIBELS,
91     MOD_SENSOR_TYPE_DBA,
92     MOD_SENSOR_TYPE_DBC,
93     MOD_SENSOR_TYPE_GRAYS,
94     MOD_SENSOR_TYPE_SIEVERTS,
95     MOD_SENSOR_TYPE_COLOR_TEMP_DEGREES_K,
96     MOD_SENSOR_TYPE_BITS,
97     MOD_SENSOR_TYPE_BYTES,
98     MOD_SENSOR_TYPE_WORDS,
99     MOD_SENSOR_TYPE_DWORDS,
100     MOD_SENSOR_TYPE_QWORDS,
101     MOD_SENSOR_TYPE_PERCENTAGE,
102     MOD_SENSOR_TYPE_PASCALS,
103     MOD_SENSOR_TYPE_COUNTS,
104     MOD_SENSOR_TYPE_GRAMS,
105     MOD_SENSOR_TYPE_NEWTON_METERS,
106     MOD_SENSOR_TYPE_HITS,
107     MOD_SENSOR_TYPE_MISSES,
108     MOD_SENSOR_TYPE_RETRIES,
109     MOD_SENSOR_TYPE_OVERRUNS,
110     MOD_SENSOR_TYPE_UNDERRUNS,
111     MOD_SENSOR_TYPE_COLLISIONS,
112     MOD_SENSOR_TYPE_PACKETS,
113     MOD_SENSOR_TYPE_MESSAGES,
114     MOD_SENSOR_TYPE_CHARACTERS,
115     MOD_SENSOR_TYPE_ERRORS,
116     MOD_SENSOR_TYPE_CORRECTED_ERRORS,
117     MOD_SENSOR_TYPE_UNCORRECTABLE_ERRORS,
118     MOD_SENSOR_TYPE_SQUARE_MILS,
119     MOD_SENSOR_TYPE_SQUARE_INCHES,
120     MOD_SENSOR_TYPE_SQUARE_FEET,
121     MOD_SENSOR_TYPE_SQUARE_CENTIMETERS,
122     MOD_SENSOR_TYPE_SQUARE_METERS,
123     MOD_SENSOR_TYPE_RADIANS_PER_SECOND,
124     MOD_SENSOR_TYPE_BEATS_PER_MINUTE,
125     MOD_SENSOR_TYPE_METERS_PER_SECOND_SQUARED,
126     MOD_SENSOR_TYPE_METERS_PER_SECOND,
127     MOD_SENSOR_TYPE_CUBIC_METER_PER_SECOND,
128     MOD_SENSOR_TYPE_MILLIMETERS_OF_MERCURY,
129     MOD_SENSOR_TYPE_RADIANS_PER_SECOND_SQUARED,
130     MOD_SENSOR_TYPE_OEM_UNIT = 0xFF,
131     MOD_SENSOR_TYPE_COUNT
132 };
133 
134 /*!
135  * \brief Structure containing all sensor trip point information.
136  */
137 struct mod_sensor_trip_point_info {
138     /*! Sensor trip point count */
139     uint32_t count;
140 };
141 
142 /*!
143  * \brief Sensor value signedness type.
144  */
145 #ifdef BUILD_HAS_SENSOR_SIGNED_VALUE
146 typedef int64_t mod_sensor_value_t;
147 #else
148 typedef uint64_t mod_sensor_value_t;
149 #endif
150 
151 #ifdef BUILD_HAS_SENSOR_EXT_ATTRIBS
152 
153 /*!
154  * \brief Structure containing all extended attributes for multi axis
155  *        information.
156  *
157  * \details Sensor information structure used to configure the sensor multi
158  *          axis values.
159  */
160 struct mod_sensor_axis_attributes {
161     /*! Axis resolution value */
162     uint32_t axis_resolution;
163 
164     /*! Axis minimum range */
165     int64_t axis_min_range;
166 
167     /*! Axis maximum range */
168     int64_t axis_max_range;
169 };
170 
171 /*!
172  * \brief Structure containing all sensor property information.
173  *
174  * \details Sensor information structure used to configure the sensor
175  *          property values.
176  */
177 struct mod_sensor_ext_properties {
178     /*! Sensor power value */
179     uint32_t sensor_power;
180 
181     /*! Further sensor property values */
182     struct mod_sensor_axis_attributes sensor_property_vals;
183 };
184 #endif
185 
186 #ifdef BUILD_HAS_SENSOR_TIMESTAMP
187 /*!
188  * \brief Structure containing all timestamp information.
189  */
190 struct mod_sensor_timestamp_info {
191     /*! Sensor timestamp support */
192     bool timestamp_support;
193 
194     /*! Sensor timestamp enabled */
195     bool enabled;
196 
197     /*!
198      * \brief Sensor timestamp exponent value
199      *
200      * \details It is the power-of-10 multiplier that is applied to the
201      *      sensor timestamps (timestamp x 10 ^ [timestamp exponent] ) to
202      *      represent it in seconds.
203      */
204     int8_t exponent;
205 };
206 #endif
207 #ifdef BUILD_HAS_SENSOR_MULTI_AXIS
208 /*!
209  * \brief Structure containing infomation for a specific sensor axis
210  *
211  * \details Sensor axis information structure used to configure the sensor HAL.
212  */
213 struct mod_sensor_axis_info {
214     /*! Sensor axis name */
215     const char *name;
216 
217     /*! SCMI sensor type */
218     enum mod_sensor_type type;
219 
220     /*!
221      * \brief Power-of-10 multiplier applied to the unit specified by
222      *      ::mod_sensor_info::type.
223      *
224      * \details Used per:
225      *
226      *      ```none
227      *      unit * 10^(unit_multiplier)
228      *      ```
229      */
230     int unit_multiplier;
231 #    ifdef BUILD_HAS_SENSOR_EXT_ATTRIBS
232     /*! Extended attributes */
233     bool extended_attribs;
234 
235     /*! Multi axis property values */
236     struct mod_sensor_axis_attributes multi_axis_properties;
237 #    endif
238 };
239 #endif
240 
241 /*!
242  * \brief Structure containing all sensor driver information.
243  *
244  * \details Sensor information structure used to configure the sensor HAL.
245  */
246 struct mod_sensor_info {
247     /*! SCMI sensor type */
248     enum mod_sensor_type type;
249 
250     /*!
251      * \brief Time (in seconds) between sensor updates.
252      *
253      * \details Set this field to 0 to indicate that the sensor does not have a
254      *      minimum update interval. This field is used with
255      *      ::mod_sensor_info::update_interval_multiplier to calculate the
256      *      actual update interval.
257      */
258     unsigned int update_interval;
259 
260     /*!
261      * \brief Power-of-10 multiplier for ::mod_sensor_info::update_interval.
262      *
263      * \details This is used to calculate the actual interval time:
264      *
265      *      ```none
266      *      actual = update_interval * 10^(update_interval_multiplier)
267      *      ```
268      */
269     int update_interval_multiplier;
270 
271     /*!
272      * \brief Power-of-10 multiplier applied to the unit specified by
273      *      ::mod_sensor_info::type.
274      *
275      * \details Used per:
276      *
277      *      ```none
278      *      unit * 10^(unit_multiplier)
279      *      ```
280      */
281     int unit_multiplier;
282 #ifdef BUILD_HAS_SENSOR_EXT_ATTRIBS
283     /*! Extended attributes information */
284     bool ext_attributes;
285 
286     /*! Sensor property values */
287     struct mod_sensor_ext_properties sensor_properties;
288 #endif
289 };
290 
291 /*!
292  * \brief Structure containing all sensor information for SCMI requests.
293  *
294  * \details Sensor information structure used serve SCMI requests.
295  */
296 struct mod_sensor_complete_info {
297     /*!
298      * \brief Sensor HAL information.
299      *
300      * \details If multi axis configuration is supported not all parameters will
301      *      be filled here.
302      */
303     struct mod_sensor_info hal_info;
304 
305     /*! Sensor trip information */
306     struct mod_sensor_trip_point_info trip_point;
307 
308 #ifdef BUILD_HAS_SENSOR_TIMESTAMP
309     /*! Sensor timestamp information */
310     struct mod_sensor_timestamp_info timestamp;
311 #endif
312 
313 #ifdef BUILD_HAS_SENSOR_MULTI_AXIS
314     /*! Sensor multi axis information */
315     struct {
316         /*! Multi axis supported feature */
317         bool support;
318         /*! Number of axis configured */
319         unsigned int axis_count;
320     } multi_axis;
321 #endif
322 };
323 
324 /*!
325  * \brief Sensor trip point detection mode
326  */
327 enum mod_sensor_trip_point_mode {
328     MOD_SENSOR_TRIP_POINT_MODE_DISABLED = 0,
329     MOD_SENSOR_TRIP_POINT_MODE_POSITIVE,
330     MOD_SENSOR_TRIP_POINT_MODE_NEGATIVE,
331     MOD_SENSOR_TRIP_POINT_MODE_TRANSITION
332 };
333 
334 /*!
335  * \brief Structure containing trip point parameters.
336  *
337  * \details Sensor trip point information structure used to configure
338  *     a trip point value.
339  */
340 struct mod_sensor_trip_point_params {
341     /*! Sensor trip point value */
342     uint64_t tp_value;
343 
344     /*! Sensor trip point mode */
345     enum mod_sensor_trip_point_mode mode;
346 };
347 
348 /*!
349  * \brief Sensor device configuration.
350  *
351  * \details Configuration structure for individual sensors.
352  */
353 struct mod_sensor_dev_config {
354     /*! Module or element identifier of the driver */
355     fwk_id_t driver_id;
356 
357     /*! API identifier of the driver */
358     fwk_id_t driver_api_id;
359 
360     /*!  Notifications identifier */
361     fwk_id_t notification_id;
362 
363     /*! Trip point API identifier */
364     fwk_id_t trip_point_api_id;
365 
366     /*! Sensor trip information */
367     struct mod_sensor_trip_point_info trip_point;
368 
369 #ifdef BUILD_HAS_SENSOR_TIMESTAMP
370     /*! Sensor timestamp default values configuration */
371     struct mod_sensor_timestamp_info timestamp;
372 #endif
373 };
374 
375 /*!
376  * \brief Sensor data.
377  *
378  * \details Sensor data structure that contains all related value reading
379  *      information.
380  */
381 struct mod_sensor_data {
382     /*! Status of the response event */
383     int status;
384 
385     /*! Sensor value */
386     union {
387         /*! Sensor N-axis value */
388         mod_sensor_value_t *axis_value;
389         /*! Sensor scalar value */
390         mod_sensor_value_t value;
391     };
392 
393 #ifdef BUILD_HAS_SENSOR_TIMESTAMP
394     /*! Timestamp value */
395     uint64_t timestamp;
396 #endif
397 
398 #ifdef BUILD_HAS_SENSOR_MULTI_AXIS
399     /*! Number of axis */
400     uint32_t axis_count;
401 #endif
402 };
403 
404 /*!
405  * \brief Sensor module configuration.
406  *
407  * \details Configuration structure sensor module.
408  */
409 struct mod_sensor_config {
410     /*!  Notifications identifier */
411     fwk_id_t notification_id;
412 
413     /*! Trip point API identifier */
414     fwk_id_t trip_point_api_id;
415 };
416 
417 /*!
418  * \brief Sensor driver API.
419  *
420  * \details Api used by this module to interface with the driver.
421  */
422 struct mod_sensor_driver_api {
423     /*!
424      * \brief Get sensor value.
425      *
426      * \param id Specific sensor device id.
427      * \param[out] value Sensor value, which can be either signed or
428      *     unsigned, depending upon the build options.
429      *
430      * \retval ::FWK_PENDING The request is pending. The driver will provide the
431      *      requested value later through the driver response API.
432      * \retval ::FWK_SUCCESS Value was read successfully.
433      * \return One of the standard framework error codes.
434      */
435     int (*get_value)(fwk_id_t id, mod_sensor_value_t *value);
436 
437     /*!
438      * \brief Get sensor information.
439      *
440      * \param id Specific sensor device id.
441      * \param[out] info The sensor information.
442      *
443      * \retval ::FWK_SUCCESS The information was read successfully.
444      * \return One of the standard framework error codes.
445      */
446     int (*get_info)(fwk_id_t id, struct mod_sensor_info *info);
447 
448 #ifdef BUILD_HAS_SENSOR_MULTI_AXIS
449     /*!
450      * \brief Get number of axis.
451      *
452      * \param id Specific sensor device id.
453      *
454      * \retval Number of axis.
455      */
456     unsigned int (*get_axis_count)(fwk_id_t id);
457 
458     /*!
459      * \brief Get axis sensor information.
460      *
461      * \param id Specific sensor device id.
462      * \param axis Specific axis.
463      * \param[out] info The sensor information.
464      *
465      * \retval ::FWK_SUCCESS The information was read successfully.
466      * \return One of the standard framework error codes.
467      */
468     int (*get_axis_info)(
469         fwk_id_t id,
470         uint32_t axis,
471         struct mod_sensor_axis_info *info);
472 #endif
473 };
474 
475 /*!
476  * \brief Sensor API.
477  */
478 struct mod_sensor_api {
479     /*!
480      * \brief Read sensor data.
481      *
482      * \details Read current sensor data.
483      *
484      * \param id Specific sensor device id.
485      * \param[out] data Sensor struct data will be returned.
486      *
487      * \retval ::FWK_SUCCESS Operation succeeded.
488      * \retval ::FWK_E_DEVICE Driver error.
489      * \retval ::FWK_E_BUSY At least one reading of the sensor data is already
490      *      on-going.
491      * \retval ::FWK_PENDING The request is pending. The requested data will be
492      *      provided via a response event.
493      * \return One of the standard framework error codes.
494      */
495     int (*get_data)(fwk_id_t id, struct mod_sensor_data *data);
496 
497     /*!
498      * \brief Get sensor information.
499      *
500      * \details Get a pointer to the sensor_info structure of a specific sensor.
501      *
502      * \param id Specific sensor device id.
503      * \param[out] info The information structure.
504      *
505      * \retval ::FWK_SUCCESS Operation succeeded.
506      * \retval ::FWK_E_DEVICE Driver error.
507      * \return One of the standard framework error codes.
508      */
509     int (*get_info)(fwk_id_t id, struct mod_sensor_complete_info *info);
510 
511     /*!
512      * \brief Set trip point.
513      *
514      * \details Set trip point sensor configuration.
515      *
516      * \param id Specific sensor device id.
517      * \param trip_point_idx Specific trip point index.
518      * \param params Pointer to trip points parameters structure.
519      *
520      * \retval FWK_SUCCESS Operation succeeded.
521      * \return One of the standard framework error codes.
522      */
523     int (*set_trip_point)(
524         fwk_id_t id,
525         uint32_t trip_point_idx,
526         struct mod_sensor_trip_point_params *params);
527 
528     /*!
529      * \brief Get trip point.
530      *
531      * \details Get trip point sensor configuration.
532      *
533      * \param id Specific sensor device id.
534      * \param trip_point_idx Specific trip point index.
535      * \param[out] params Pointer to trip points parameters structure.
536      *
537      * \retval FWK_SUCCESS Operation succeeded.
538      * \return One of the standard framework error codes.
539      */
540     int (*get_trip_point)(
541         fwk_id_t id,
542         uint32_t trip_point_idx,
543         struct mod_sensor_trip_point_params *params);
544 
545 #ifdef BUILD_HAS_SENSOR_TIMESTAMP
546     /*!
547      * \brief Configure timestamp
548      *
549      * \details Set timestamp configuration
550      *
551      * \param id Specific sensor device id.
552      * \param config Timestamp configuration structure.
553      *
554      * \retval FWK_SUCCESS Operation succeeded.
555      * \retval FWK_E_SUPPORT Operation not supported by sensor.
556      * \return One of the standard framework error codes.
557      */
558     int (*set_timestamp_config)(
559         fwk_id_t id,
560         const struct mod_sensor_timestamp_info *config);
561 
562     /*!
563      * \brief Read timestamp configuration
564      *
565      * \details Get timestamp configuration
566      *
567      * \param id Specific sensor device id.
568      * \param[out] config Timestamp configuration structure.
569      *
570      * \retval FWK_SUCCESS Operation succeeded.
571      * \return One of the standard framework error codes.
572      */
573     int (*get_timestamp_config)(
574         fwk_id_t id,
575         struct mod_sensor_timestamp_info *config);
576 
577     /*!
578      * \brief Get axis sensor information.
579      *
580      * \param id Specific sensor device id.
581      * \param axis Specific axis.
582      * \param[out] info The sensor information.
583      *
584      * \retval ::FWK_SUCCESS The information was read successfully.
585      * \return One of the standard framework error codes.
586      */
587     int (*get_axis_info)(
588         fwk_id_t id,
589         uint32_t axis,
590         struct mod_sensor_axis_info *info);
591 #endif
592 };
593 
594 /*!
595  * \brief Driver response parameters.
596  */
597 struct mod_sensor_driver_resp_params {
598     /*! Status of the requested operation */
599     int status;
600 
601     /*! Sensor value */
602     union {
603         /*! Sensor N-axis value */
604         mod_sensor_value_t *axis_value;
605         /*! Sensor scalar value */
606         mod_sensor_value_t value;
607     };
608 };
609 
610 /*!
611  * \brief Driver response API.
612  *
613  * \details API used by the driver to notify the HAL when a pending request
614  *      has completed.
615  */
616 struct mod_sensor_driver_response_api {
617     /*!
618      * \brief Inform the completion of a sensor reading.
619      *
620      * \param id Specific sensor device identifier.
621      * \param[out] response The response data structure.
622      */
623     void (*reading_complete)(fwk_id_t id,
624                              struct mod_sensor_driver_resp_params *response);
625 };
626 
627 /*!
628  * \brief API indices.
629  */
630 enum mod_sensor_api_idx {
631     /*!
632      * \brief Driver API index.
633      *
634      * \note This API implements the ::mod_sensor_api interface.
635      */
636     MOD_SENSOR_API_IDX_SENSOR,
637 
638     /*!
639      * \brief Driver response API.
640      */
641     MOD_SENSOR_API_IDX_DRIVER_RESPONSE,
642 
643     /*!
644      * \brief Number of defined APIs.
645      */
646     MOD_SENSOR_API_IDX_COUNT,
647 };
648 
649 /*!
650  * \brief Module API identifier.
651  */
652 static const fwk_id_t mod_sensor_api_id_sensor =
653     FWK_ID_API_INIT(FWK_MODULE_IDX_SENSOR, MOD_SENSOR_API_IDX_SENSOR);
654 
655 /*!
656  * \brief Driver input API identifier.
657  */
658 static const fwk_id_t mod_sensor_api_id_driver_response =
659     FWK_ID_API_INIT(FWK_MODULE_IDX_SENSOR, MOD_SENSOR_API_IDX_DRIVER_RESPONSE);
660 
661 /*!
662  * \brief Shared event parameters.
663  */
664 struct mod_sensor_event_params {
665     /*! Sensor value pointer */
666     struct mod_sensor_data *sensor_data;
667 };
668 
669 /*!
670  * Sensor module read request event index
671  */
672 #define MOD_SENSOR_EVENT_IDX_READ_REQUEST    0
673 
674 /*!
675  * \brief Read request event identifier.
676  *
677  * \details Clients which expect to receive a response event from this module
678  *      should use this identifier to properly identify the response.
679  */
680 static const fwk_id_t mod_sensor_event_id_read_request =
681     FWK_ID_EVENT_INIT(FWK_MODULE_IDX_SENSOR, MOD_SENSOR_EVENT_IDX_READ_REQUEST);
682 
683 /*!
684  * \}
685  */
686 
687 /*!
688  * \}
689  */
690 
691 #endif /* MOD_SENSOR_H */
692