1 /*
2 * Arm SCP/MCP Software
3 * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "sensor.h"
9
10 #ifdef BUILD_HAS_SCMI_SENSOR_EVENTS
11 # include <mod_scmi_sensor.h>
12 #endif
13 #include <mod_sensor.h>
14
15 #include <fwk_assert.h>
16 #include <fwk_core.h>
17 #include <fwk_event.h>
18 #include <fwk_id.h>
19 #include <fwk_mm.h>
20 #include <fwk_module.h>
21 #include <fwk_module_idx.h>
22 #include <fwk_status.h>
23 #include <fwk_string.h>
24
25 #include <stdbool.h>
26 #include <stddef.h>
27 #include <stdint.h>
28
29 static struct sensor_dev_ctx *ctx_table;
30 static struct mod_sensor_ctx sensor_mod_ctx;
31
sensor_get_ctx(fwk_id_t id)32 struct sensor_dev_ctx *sensor_get_ctx(fwk_id_t id)
33 {
34 return ctx_table + fwk_id_get_element_idx(id);
35 }
36
get_ctx_if_valid_call(fwk_id_t id,const void * data,struct sensor_dev_ctx ** ctx)37 static int get_ctx_if_valid_call(
38 fwk_id_t id,
39 const void *data,
40 struct sensor_dev_ctx **ctx)
41 {
42 fwk_assert(ctx != NULL);
43
44 if (!fwk_expect(data != NULL)) {
45 return FWK_E_PARAM;
46 }
47
48 *ctx = ctx_table + fwk_id_get_element_idx(id);
49
50 return FWK_SUCCESS;
51 }
52
sensor_data_copy(struct mod_sensor_data * dest,const struct mod_sensor_data * origin)53 static inline void sensor_data_copy(
54 struct mod_sensor_data *dest,
55 const struct mod_sensor_data *origin)
56 {
57 #ifdef BUILD_HAS_SENSOR_MULTI_AXIS
58 mod_sensor_value_t *value = dest->axis_value;
59 #endif
60
61 fwk_str_memcpy(dest, origin, sizeof(struct mod_sensor_data));
62
63 #ifdef BUILD_HAS_SENSOR_MULTI_AXIS
64 if (dest->axis_count > 1) {
65 dest->axis_value = value;
66 fwk_str_memcpy(
67 dest->axis_value,
68 origin->axis_value,
69 sizeof(uint64_t) * dest->axis_count);
70 }
71 #endif
72 }
73
74 #ifdef BUILD_HAS_SCMI_SENSOR_EVENTS
trip_point_evaluate(struct sensor_trip_point_ctx * ctx,uint64_t value)75 static bool trip_point_evaluate(
76 struct sensor_trip_point_ctx *ctx,
77 uint64_t value)
78 {
79 uint64_t threshold;
80 bool new_above_threshold, trigger = false;
81
82 threshold = ctx->params.tp_value;
83 new_above_threshold = value > threshold;
84
85 switch (ctx->params.mode) {
86 case MOD_SENSOR_TRIP_POINT_MODE_POSITIVE:
87 if (!ctx->above_threshold && value > threshold)
88 trigger = true;
89 break;
90
91 case MOD_SENSOR_TRIP_POINT_MODE_NEGATIVE:
92 if (ctx->above_threshold && (value <= threshold))
93 trigger = true;
94 break;
95
96 case MOD_SENSOR_TRIP_POINT_MODE_TRANSITION:
97 if ((!ctx->above_threshold && value > threshold) ||
98 (ctx->above_threshold && value <= threshold))
99 trigger = true;
100 break;
101
102 default:
103 break;
104 }
105
106 ctx->above_threshold = new_above_threshold;
107 return trigger;
108 }
109 #endif
110
111 #ifdef BUILD_HAS_SCMI_SENSOR_EVENTS
trip_point_process(fwk_id_t id,struct mod_sensor_data * data)112 static void trip_point_process(fwk_id_t id, struct mod_sensor_data *data)
113 {
114 struct sensor_dev_ctx *ctx;
115 unsigned int i;
116
117 fwk_check(!fwk_id_is_equal(id, FWK_ID_NONE));
118 ctx = ctx_table + fwk_id_get_element_idx(id);
119
120 if (!ctx->trip_point_ctx->enabled) {
121 return;
122 }
123
124 for (i = 0; i < ctx->config->trip_point.count; i++) {
125 if (trip_point_evaluate(&(ctx->trip_point_ctx[i]), data->value)) {
126 /* Handle trip point event*/
127 if (sensor_mod_ctx.sensor_trip_point_api != NULL)
128 sensor_mod_ctx.sensor_trip_point_api->notify_sensor_trip_point(
129 id, ctx->trip_point_ctx->above_threshold, i);
130 }
131 }
132 }
133 #endif
134
is_sensor_enabled(fwk_id_t id,bool * sensor_is_enabled)135 static int is_sensor_enabled(fwk_id_t id, bool *sensor_is_enabled)
136 {
137 int status;
138
139 if (fwk_id_is_type(id, FWK_ID_TYPE_ELEMENT)) {
140 struct mod_sensor_complete_info complete_info;
141 struct sensor_dev_ctx *ctx;
142
143 ctx = &ctx_table[fwk_id_get_element_idx(id)];
144
145 status = ctx->driver_api->get_info(
146 ctx->config->driver_id, &(complete_info.hal_info));
147
148 if (status != FWK_SUCCESS) {
149 return status;
150 }
151
152 *sensor_is_enabled = !complete_info.hal_info.disabled;
153
154 return FWK_SUCCESS;
155 }
156
157 return FWK_E_PARAM;
158 }
159
160 /*
161 * Module API
162 */
get_data(fwk_id_t id,struct mod_sensor_data * data)163 static int get_data(fwk_id_t id, struct mod_sensor_data *data)
164 {
165 int status;
166 bool sensor_enabled;
167 struct sensor_dev_ctx *ctx;
168 struct fwk_event req;
169 struct mod_sensor_event_params *event_params =
170 (struct mod_sensor_event_params *)req.params;
171
172 status = get_ctx_if_valid_call(id, data, &ctx);
173 if (status != FWK_SUCCESS) {
174 return status;
175 }
176
177 status = is_sensor_enabled(id, &sensor_enabled);
178 if (status != FWK_SUCCESS) {
179 return status;
180 }
181
182 if (!sensor_enabled) {
183 return FWK_E_SUPPORT;
184 }
185
186 if (ctx->concurrency_readings.dequeuing) {
187 /* Prevent new reading request while dequeuing pending readings
188 * cached data is returned
189 */
190 sensor_data_copy(data, &ctx->last_read);
191 return ctx->last_read.status;
192 }
193
194 if (ctx->concurrency_readings.pending_requests == 0) {
195 status = ctx->driver_api->get_value(
196 ctx->config->driver_id, &ctx->last_read.value);
197 ctx->last_read.status = status;
198 if (status == FWK_SUCCESS) {
199 #ifdef BUILD_HAS_SCMI_SENSOR_EVENTS
200 trip_point_process(id, &ctx->last_read);
201 #endif
202 #ifdef BUILD_HAS_SENSOR_TIMESTAMP
203 ctx->last_read.timestamp = sensor_get_timestamp(id);
204 #endif
205 sensor_data_copy(data, &ctx->last_read);
206
207 return status;
208 } else if (status != FWK_PENDING) {
209 return status;
210 }
211 }
212
213 if (ctx->concurrency_readings.pending_requests >=
214 SENSOR_MAX_PENDING_REQUESTS) {
215 return FWK_E_BUSY;
216 }
217
218 req = (struct fwk_event){
219 .target_id = id,
220 .id = mod_sensor_event_id_read_request,
221 .response_requested = true,
222 };
223
224 /* Save data address to copy return values in there */
225 event_params->sensor_data = data;
226
227 status = fwk_put_event(&req);
228 if (status != FWK_SUCCESS) {
229 return status;
230 }
231
232 ctx->concurrency_readings.pending_requests++;
233 /*
234 * We return FWK_PENDING here to indicate to the caller that the
235 * result of the request is pending and will arrive later through
236 * an event.
237 */
238 return FWK_PENDING;
239 }
240
get_info(fwk_id_t id,struct mod_sensor_complete_info * info)241 static int get_info(fwk_id_t id, struct mod_sensor_complete_info *info)
242 {
243 int status;
244 struct sensor_dev_ctx *ctx;
245
246 status = get_ctx_if_valid_call(id, info, &ctx);
247 if (status != FWK_SUCCESS) {
248 return status;
249 }
250
251 status = ctx->driver_api->get_info(ctx->config->driver_id, &info->hal_info);
252 if (!fwk_expect(status == FWK_SUCCESS)) {
253 return FWK_E_DEVICE;
254 }
255 info->trip_point = ctx->config->trip_point;
256
257 #ifdef BUILD_HAS_SENSOR_TIMESTAMP
258 status = sensor_get_timestamp_config(id, &info->timestamp);
259 if (status == FWK_E_SUPPORT) {
260 info->timestamp.timestamp_support = false;
261 } else {
262 return status;
263 }
264 #endif
265 #ifdef BUILD_HAS_SENSOR_MULTI_AXIS
266 if (ctx->axis_count > 1) {
267 info->multi_axis.support = true;
268 info->multi_axis.axis_count = ctx->axis_count;
269 }
270 #endif
271
272 return FWK_SUCCESS;
273 }
274
sensor_get_trip_point(fwk_id_t id,uint32_t trip_point_idx,struct mod_sensor_trip_point_params * params)275 static int sensor_get_trip_point(
276 fwk_id_t id,
277 uint32_t trip_point_idx,
278 struct mod_sensor_trip_point_params *params)
279 {
280 struct sensor_dev_ctx *ctx;
281
282 fwk_check(params != NULL);
283
284 ctx = ctx_table + fwk_id_get_element_idx(id);
285
286 if (trip_point_idx >= ctx->config->trip_point.count) {
287 return FWK_E_PARAM;
288 }
289
290 *params = ctx->trip_point_ctx[trip_point_idx].params;
291
292 return FWK_SUCCESS;
293 }
294
sensor_set_trip_point(fwk_id_t id,uint32_t trip_point_idx,const struct mod_sensor_trip_point_params * params)295 static int sensor_set_trip_point(
296 fwk_id_t id,
297 uint32_t trip_point_idx,
298 const struct mod_sensor_trip_point_params *params)
299 {
300 struct sensor_dev_ctx *ctx;
301
302 if (params == NULL) {
303 return FWK_E_PARAM;
304 }
305
306 ctx = ctx_table + fwk_id_get_element_idx(id);
307
308 if (trip_point_idx >= ctx->config->trip_point.count) {
309 return FWK_E_PARAM;
310 }
311
312 ctx->trip_point_ctx[trip_point_idx].params = *params;
313
314 /* Clear the trip point flag */
315 ctx->trip_point_ctx[trip_point_idx].above_threshold = false;
316 return FWK_SUCCESS;
317 }
318
sensor_enable(fwk_id_t id)319 static int sensor_enable(fwk_id_t id)
320 {
321 struct sensor_dev_ctx *ctx;
322
323 ctx = sensor_get_ctx(id);
324
325 if (ctx->driver_api->enable != NULL) {
326 return ctx->driver_api->enable(id);
327 }
328
329 return FWK_E_SUPPORT;
330 }
331
sensor_disable(fwk_id_t id)332 static int sensor_disable(fwk_id_t id)
333 {
334 struct sensor_dev_ctx *ctx;
335
336 ctx = sensor_get_ctx(id);
337
338 if (ctx->driver_api->disable != NULL) {
339 return ctx->driver_api->disable(id);
340 }
341
342 return FWK_E_SUPPORT;
343 }
344
sensor_set_update_interval(fwk_id_t id,unsigned int time_interval,int time_interval_multiplier)345 static int sensor_set_update_interval(
346 fwk_id_t id,
347 unsigned int time_interval,
348 int time_interval_multiplier)
349 {
350 struct sensor_dev_ctx *ctx;
351
352 if (!fwk_id_is_type(id, FWK_ID_TYPE_ELEMENT)) {
353 return FWK_E_PARAM;
354 }
355
356 ctx = &ctx_table[fwk_id_get_element_idx(id)];
357
358 if (ctx->driver_api->set_update_interval == NULL) {
359 return FWK_E_SUPPORT;
360 }
361
362 return ctx->driver_api->set_update_interval(
363 id, time_interval, time_interval_multiplier);
364 }
365
sensor_get_update_interval(fwk_id_t id,unsigned int * time_interval,int * time_interval_multiplier)366 static int sensor_get_update_interval(
367 fwk_id_t id,
368 unsigned int *time_interval,
369 int *time_interval_multiplier)
370 {
371 int status;
372 struct sensor_dev_ctx *ctx;
373 struct mod_sensor_complete_info complete_info;
374
375 if (!fwk_id_is_type(id, FWK_ID_TYPE_ELEMENT)) {
376 return FWK_E_PARAM;
377 }
378
379 ctx = &ctx_table[fwk_id_get_element_idx(id)];
380
381 status = ctx->driver_api->get_info(
382 ctx->config->driver_id, &(complete_info.hal_info));
383
384 if (status != FWK_SUCCESS) {
385 return status;
386 }
387
388 *time_interval = complete_info.hal_info.update_interval;
389 *time_interval_multiplier =
390 complete_info.hal_info.update_interval_multiplier;
391
392 return FWK_SUCCESS;
393 }
394
395 static struct mod_sensor_api sensor_api = {
396 .get_data = get_data,
397 .get_info = get_info,
398 .get_trip_point = sensor_get_trip_point,
399 .set_trip_point = sensor_set_trip_point,
400 .enable = sensor_enable,
401 .disable = sensor_disable,
402 .set_update_interval = sensor_set_update_interval,
403 .get_update_interval = sensor_get_update_interval,
404 #ifdef BUILD_HAS_SENSOR_TIMESTAMP
405 .set_timestamp_config = sensor_set_timestamp_config,
406 .get_timestamp_config = sensor_get_timestamp_config,
407 #endif
408 #ifdef BUILD_HAS_SENSOR_MULTI_AXIS
409 .get_axis_info = sensor_get_axis_info,
410 #endif
411 };
412
413 /*
414 * Driver response API.
415 */
reading_complete(fwk_id_t dev_id,struct mod_sensor_driver_resp_params * response)416 static void reading_complete(fwk_id_t dev_id,
417 struct mod_sensor_driver_resp_params *response)
418 {
419 int status = FWK_SUCCESS;
420 struct fwk_event event;
421 struct sensor_dev_ctx *ctx;
422
423 if (!fwk_expect(fwk_id_get_module_idx(dev_id) == FWK_MODULE_IDX_SENSOR)) {
424 return;
425 }
426
427 ctx = &ctx_table[fwk_id_get_element_idx(dev_id)];
428 event = (struct fwk_event) {
429 .id = mod_sensor_event_id_read_complete,
430 .source_id = ctx->config->driver_id,
431 .target_id = dev_id,
432 };
433
434 if (response != NULL) {
435 ctx->last_read.status = response->status;
436
437 #ifdef BUILD_HAS_SENSOR_TIMESTAMP
438 ctx->last_read.timestamp = sensor_get_timestamp(dev_id);
439 #endif
440 #ifdef BUILD_HAS_SENSOR_MULTI_AXIS
441 if (ctx->axis_count > 1) {
442 fwk_str_memcpy(
443 ctx->last_read.axis_value,
444 response->axis_value,
445 sizeof(uint64_t) * ctx->axis_count);
446 } else {
447 ctx->last_read.value = response->value;
448 }
449 #else
450 ctx->last_read.value = response->value;
451 #endif
452
453 #ifdef BUILD_HAS_SCMI_SENSOR_EVENTS
454 trip_point_process(dev_id, &ctx->last_read);
455 #endif
456 } else {
457 ctx->last_read.status = FWK_E_DEVICE;
458 }
459
460 ctx->concurrency_readings.dequeuing = true;
461
462 status = fwk_put_event(&event);
463 fwk_assert(status == FWK_SUCCESS);
464 }
465
466 static struct mod_sensor_driver_response_api sensor_driver_response_api = {
467 .reading_complete = reading_complete,
468 };
469
470 /*
471 * Framework handlers
472 */
sensor_init(fwk_id_t module_id,unsigned int element_count,const void * data)473 static int sensor_init(
474 fwk_id_t module_id,
475 unsigned int element_count,
476 const void *data)
477 {
478 struct mod_sensor_config *config;
479
480 ctx_table = fwk_mm_calloc(element_count, sizeof(ctx_table[0]));
481 fwk_str_memset(&sensor_mod_ctx, 0, sizeof(sensor_mod_ctx));
482 config = (struct mod_sensor_config *)data;
483
484 sensor_mod_ctx.config = config;
485 return FWK_SUCCESS;
486 }
487
sensor_dev_init(fwk_id_t element_id,unsigned int unused,const void * data)488 static int sensor_dev_init(fwk_id_t element_id,
489 unsigned int unused,
490 const void *data)
491 {
492 struct sensor_dev_ctx *ctx;
493 struct mod_sensor_dev_config *config;
494
495 ctx = ctx_table + fwk_id_get_element_idx(element_id);
496
497 fwk_check(data != NULL);
498 config = (struct mod_sensor_dev_config*)data;
499
500 ctx->config = config;
501
502 if (config->trip_point.count > 0) {
503 ctx->trip_point_ctx = fwk_mm_calloc(
504 config->trip_point.count, sizeof(struct sensor_trip_point_ctx));
505 ctx->trip_point_ctx->enabled = true;
506 } else {
507 ctx->trip_point_ctx = NULL;
508 }
509
510 /* Pre-init last read with an invalid status */
511 ctx->last_read.status = FWK_E_DEVICE;
512
513 #ifndef BUILD_HAS_SENSOR_MULTI_AXIS
514 ctx->axis_count = 1;
515 #endif
516 #ifdef BUILD_HAS_SENSOR_TIMESTAMP
517 return sensor_timestamp_dev_init(element_id, ctx);
518 #else
519 return FWK_SUCCESS;
520 #endif
521 }
522
sensor_bind(fwk_id_t id,unsigned int round)523 static int sensor_bind(fwk_id_t id, unsigned int round)
524 {
525 struct sensor_dev_ctx *ctx;
526 int status;
527 struct mod_sensor_driver_api *driver = NULL;
528
529 if (round > 0) {
530 /*
531 * Only bind in first round of calls
532 */
533 return FWK_SUCCESS;
534 }
535 if (fwk_id_is_type(id, FWK_ID_TYPE_MODULE)) {
536 if (sensor_mod_ctx.config == NULL) {
537 return FWK_SUCCESS;
538 }
539
540 #ifdef BUILD_HAS_NOTIFICATION
541 if (fwk_id_is_equal(
542 sensor_mod_ctx.config->notification_id, FWK_ID_NONE)) {
543 return FWK_SUCCESS;
544 }
545
546 return fwk_module_bind(
547 sensor_mod_ctx.config->notification_id,
548 sensor_mod_ctx.config->trip_point_api_id,
549 &sensor_mod_ctx.sensor_trip_point_api);
550 #else
551 return FWK_SUCCESS;
552 #endif
553 }
554 ctx = ctx_table + fwk_id_get_element_idx(id);
555 /* Bind to driver */
556 status = fwk_module_bind(ctx->config->driver_id,
557 ctx->config->driver_api_id,
558 &driver);
559 if (status != FWK_SUCCESS) {
560 return status;
561 }
562
563 /* Validate driver API */
564 if ((driver == NULL) || (driver->get_value == NULL)) {
565 return FWK_E_DATA;
566 }
567
568 ctx->driver_api = driver;
569
570 return FWK_SUCCESS;
571 }
572
573 #ifdef BUILD_HAS_SENSOR_MULTI_AXIS
sensor_start(fwk_id_t id)574 int sensor_start(fwk_id_t id)
575 {
576 int status;
577
578 if (fwk_id_is_type(id, FWK_ID_TYPE_MODULE)) {
579 return FWK_SUCCESS;
580 }
581 status = sensor_axis_start(id);
582 if (status != FWK_SUCCESS) {
583 return status;
584 }
585
586 return FWK_SUCCESS;
587 }
588 #endif
589
sensor_process_bind_request(fwk_id_t source_id,fwk_id_t target_id,fwk_id_t api_id,const void ** api)590 static int sensor_process_bind_request(fwk_id_t source_id,
591 fwk_id_t target_id,
592 fwk_id_t api_id,
593 const void **api)
594 {
595 struct sensor_dev_ctx *ctx;
596 fwk_id_t driver_id;
597
598 if (fwk_id_is_equal(api_id, mod_sensor_api_id_sensor)) {
599 *api = &sensor_api;
600
601 return FWK_SUCCESS;
602 }
603
604 if (fwk_id_is_equal(api_id, mod_sensor_api_id_driver_response)) {
605 if (!fwk_id_is_type(target_id, FWK_ID_TYPE_ELEMENT)) {
606 return FWK_E_PARAM;
607 }
608
609 ctx = ctx_table + fwk_id_get_element_idx(target_id);
610 driver_id = ctx->config->driver_id;
611
612 /* Allow element to sub-element binding */
613 if ((fwk_id_get_module_idx(driver_id) ==
614 fwk_id_get_module_idx(source_id)) &&
615 (fwk_id_get_element_idx(driver_id) ==
616 fwk_id_get_element_idx(source_id))) {
617
618 *api = &sensor_driver_response_api;
619
620 return FWK_SUCCESS;
621 } else {
622 return FWK_E_ACCESS;
623 }
624 }
625
626 return FWK_E_PARAM;
627 }
628
process_pending_requests(fwk_id_t dev_id,const struct mod_sensor_data * event_params)629 static int process_pending_requests(
630 fwk_id_t dev_id,
631 const struct mod_sensor_data *event_params)
632 {
633 int status;
634 bool list_is_empty;
635 struct fwk_event delayed_response;
636 struct mod_sensor_event_params *response_params =
637 (struct mod_sensor_event_params *)delayed_response.params;
638 struct sensor_dev_ctx *ctx;
639
640 status = fwk_is_delayed_response_list_empty(dev_id, &list_is_empty);
641 if (status != FWK_SUCCESS) {
642 return status;
643 }
644
645 ctx = &ctx_table[fwk_id_get_element_idx(dev_id)];
646
647 for (; !list_is_empty && ctx->concurrency_readings.pending_requests > 0;
648 ctx->concurrency_readings.pending_requests--) {
649 status = fwk_get_first_delayed_response(dev_id, &delayed_response);
650 if (status != FWK_SUCCESS) {
651 return status;
652 }
653
654 sensor_data_copy(response_params->sensor_data, &ctx->last_read);
655
656 status = fwk_put_event(&delayed_response);
657 if (status != FWK_SUCCESS) {
658 return status;
659 }
660
661 status = fwk_is_delayed_response_list_empty(dev_id, &list_is_empty);
662 if (status != FWK_SUCCESS) {
663 return status;
664 }
665 }
666
667 ctx->concurrency_readings.pending_requests = 0;
668 ctx->concurrency_readings.dequeuing = false;
669
670 return FWK_SUCCESS;
671 }
672
sensor_process_event(const struct fwk_event * event,struct fwk_event * resp_event)673 static int sensor_process_event(const struct fwk_event *event,
674 struct fwk_event *resp_event)
675 {
676 int status;
677 struct sensor_dev_ctx *ctx;
678 struct fwk_event read_req_event;
679 struct mod_sensor_event_params *event_params =
680 (struct mod_sensor_event_params *)read_req_event.params;
681 enum mod_sensor_event_idx event_id_type;
682
683 if (!fwk_module_is_valid_element_id(event->target_id)) {
684 return FWK_E_PARAM;
685 }
686
687 ctx = ctx_table + fwk_id_get_element_idx(event->target_id);
688
689 event_id_type = (enum mod_sensor_event_idx)fwk_id_get_event_idx(event->id);
690
691 switch (event_id_type) {
692 case SENSOR_EVENT_IDX_READ_REQUEST:
693 if (ctx->concurrency_readings.pending_requests == 1) {
694 /*
695 * We keep the cookie event of the request that triggers the
696 * reading.
697 */
698 ctx->cookie = event->cookie;
699 }
700 resp_event->is_delayed_response = true;
701
702 return FWK_SUCCESS;
703
704 case SENSOR_EVENT_IDX_READ_COMPLETE:
705 status = fwk_get_delayed_response(
706 event->target_id, ctx->cookie, &read_req_event);
707 if (status != FWK_SUCCESS) {
708 return status;
709 }
710
711 sensor_data_copy(
712 (struct mod_sensor_data *)event_params->sensor_data,
713 &ctx->last_read);
714
715 status = fwk_put_event(&read_req_event);
716 if (status != FWK_SUCCESS) {
717 return status;
718 }
719
720 /*
721 * After a read complete event all pending requests are processed.
722 * We are processing pending events until it reaches a new reading
723 * or the event queue is empty.
724 */
725 return process_pending_requests(
726 event->target_id, (const struct mod_sensor_data *)event->params);
727
728 default:
729 return FWK_E_PARAM;
730 }
731 }
732
733 const struct fwk_module module_sensor = {
734 .api_count = (unsigned int)MOD_SENSOR_API_IDX_COUNT,
735 .event_count = (unsigned int)SENSOR_EVENT_IDX_COUNT,
736 .type = FWK_MODULE_TYPE_HAL,
737 .init = sensor_init,
738 .element_init = sensor_dev_init,
739 .bind = sensor_bind,
740 #ifdef BUILD_HAS_SENSOR_MULTI_AXIS
741 .start = sensor_start,
742 #endif
743 .process_bind_request = sensor_process_bind_request,
744 .process_event = sensor_process_event,
745 };
746