1 /*
2  * Copyright (c) 2024 Intel Corporation
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 
6 #include <zephyr/logging/log.h>
7 #include <zephyr/rtio/work.h>
8 
9 #include "mmc56x3.h"
10 
11 LOG_MODULE_DECLARE(MMC56X3, CONFIG_SENSOR_LOG_LEVEL);
12 
mmc56x3_submit_sync(struct rtio_iodev_sqe * iodev_sqe)13 void mmc56x3_submit_sync(struct rtio_iodev_sqe *iodev_sqe)
14 {
15 	uint32_t min_buf_len = sizeof(struct mmc56x3_encoded_data);
16 	int rc;
17 	uint8_t *buf;
18 	uint32_t buf_len;
19 
20 	const struct sensor_read_config *cfg = iodev_sqe->sqe.iodev->data;
21 	const struct device *dev = cfg->sensor;
22 	const struct sensor_chan_spec *const channels = cfg->channels;
23 	const size_t num_channels = cfg->count;
24 
25 	rc = rtio_sqe_rx_buf(iodev_sqe, min_buf_len, min_buf_len, &buf, &buf_len);
26 	if (rc != 0) {
27 		LOG_ERR("Failed to get a read buffer of size %u bytes", min_buf_len);
28 		rtio_iodev_sqe_err(iodev_sqe, rc);
29 		return;
30 	}
31 
32 	struct mmc56x3_encoded_data *edata;
33 
34 	edata = (struct mmc56x3_encoded_data *)buf;
35 	edata->header.timestamp = k_ticks_to_ns_floor64(k_uptime_ticks());
36 	edata->has_temp = 0;
37 	edata->has_magn_x = 0;
38 	edata->has_magn_y = 0;
39 	edata->has_magn_z = 0;
40 
41 	/* Check if the requested channels are supported */
42 	for (size_t i = 0; i < num_channels; i++) {
43 		switch (channels[i].chan_type) {
44 		case SENSOR_CHAN_AMBIENT_TEMP:
45 			edata->has_temp = 1;
46 			break;
47 		case SENSOR_CHAN_MAGN_X:
48 			edata->has_magn_x = 1;
49 			break;
50 		case SENSOR_CHAN_MAGN_Y:
51 			edata->has_magn_y = 1;
52 			break;
53 		case SENSOR_CHAN_MAGN_Z:
54 			edata->has_magn_z = 1;
55 			break;
56 		case SENSOR_CHAN_MAGN_XYZ:
57 			edata->has_magn_x = 1;
58 			edata->has_magn_y = 1;
59 			edata->has_magn_z = 1;
60 			break;
61 		case SENSOR_CHAN_ALL:
62 			edata->has_temp = 1;
63 			edata->has_magn_x = 1;
64 			edata->has_magn_y = 1;
65 			edata->has_magn_z = 1;
66 			break;
67 		default:
68 			continue;
69 			break;
70 		}
71 	}
72 
73 	rc = mmc56x3_sample_fetch_helper(dev, SENSOR_CHAN_ALL, &edata->data);
74 	if (rc != 0) {
75 		LOG_ERR("Failed to fetch samples");
76 		rtio_iodev_sqe_err(iodev_sqe, rc);
77 		return;
78 	}
79 
80 	rtio_iodev_sqe_ok(iodev_sqe, 0);
81 }
82 
mmc56x3_submit(const struct device * dev,struct rtio_iodev_sqe * iodev_sqe)83 void mmc56x3_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe)
84 {
85 	struct rtio_work_req *req = rtio_work_req_alloc();
86 
87 	if (req == NULL) {
88 		LOG_ERR("RTIO work item allocation failed. Consider to increase "
89 			"CONFIG_RTIO_WORKQ_POOL_ITEMS.");
90 		rtio_iodev_sqe_err(iodev_sqe, -ENOMEM);
91 		return;
92 	}
93 
94 	rtio_work_req_submit(req, iodev_sqe, mmc56x3_submit_sync);
95 }
96