1 /*
2 * Copyright (c) 2024 Intel Corporation
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6 #include "mmc56x3.h"
7 #include <math.h>
8
mmc56x3_decoder_get_frame_count(const uint8_t * buffer,struct sensor_chan_spec chan_spec,uint16_t * frame_count)9 static int mmc56x3_decoder_get_frame_count(const uint8_t *buffer, struct sensor_chan_spec chan_spec,
10 uint16_t *frame_count)
11 {
12 const struct mmc56x3_encoded_data *edata = (const struct mmc56x3_encoded_data *)buffer;
13 int32_t ret = -ENOTSUP;
14
15 if (chan_spec.chan_idx != 0) {
16 return ret;
17 }
18
19 /* This sensor lacks a FIFO; there will always only be one frame at a time. */
20 switch (chan_spec.chan_type) {
21 case SENSOR_CHAN_AMBIENT_TEMP:
22 *frame_count = edata->has_temp ? 1 : 0;
23 break;
24 case SENSOR_CHAN_MAGN_X:
25 *frame_count = edata->has_magn_x ? 1 : 0;
26 break;
27 case SENSOR_CHAN_MAGN_Y:
28 *frame_count = edata->has_magn_y ? 1 : 0;
29 break;
30 case SENSOR_CHAN_MAGN_Z:
31 *frame_count = edata->has_magn_z ? 1 : 0;
32 break;
33 case SENSOR_CHAN_MAGN_XYZ:
34 *frame_count =
35 ((edata->has_magn_x && edata->has_magn_y && edata->has_magn_z) ? 1 : 0);
36 break;
37 default:
38 return ret;
39 }
40
41 if (*frame_count > 0) {
42 ret = 0;
43 }
44
45 return ret;
46 }
47
mmc56x3_decoder_get_size_info(struct sensor_chan_spec chan_spec,size_t * base_size,size_t * frame_size)48 static int mmc56x3_decoder_get_size_info(struct sensor_chan_spec chan_spec, size_t *base_size,
49 size_t *frame_size)
50 {
51 switch (chan_spec.chan_type) {
52 case SENSOR_CHAN_AMBIENT_TEMP:
53 case SENSOR_CHAN_MAGN_X:
54 case SENSOR_CHAN_MAGN_Y:
55 case SENSOR_CHAN_MAGN_Z:
56 *base_size = sizeof(struct sensor_q31_sample_data);
57 *frame_size = sizeof(struct sensor_q31_sample_data);
58 case SENSOR_CHAN_MAGN_XYZ:
59 *base_size = sizeof(struct sensor_three_axis_data);
60 *frame_size = sizeof(struct sensor_three_axis_sample_data);
61 return 0;
62 default:
63 return -ENOTSUP;
64 }
65 }
66
mmc56x3_decoder_decode(const uint8_t * buffer,struct sensor_chan_spec chan_spec,uint32_t * fit,uint16_t max_count,void * data_out)67 static int mmc56x3_decoder_decode(const uint8_t *buffer, struct sensor_chan_spec chan_spec,
68 uint32_t *fit, uint16_t max_count, void *data_out)
69 {
70 const struct mmc56x3_encoded_data *edata = (const struct mmc56x3_encoded_data *)buffer;
71 const struct mmc56x3_data *data = &edata->data;
72
73 if (*fit != 0) {
74 return 0;
75 }
76
77 switch (chan_spec.chan_type) {
78 case SENSOR_CHAN_AMBIENT_TEMP:
79 if (edata->has_temp) {
80 struct sensor_q31_data *out = data_out;
81
82 out->header.base_timestamp_ns = edata->header.timestamp;
83 out->header.reading_count = 1;
84 out->readings[0].temperature = MMC56X3_TEMP_CONV_Q7_24_BASE +
85 data->temp * MMC56X3_TEMP_CONV_Q7_24_RES;
86 out->shift = MMC56X3_TEMP_SHIFT;
87 } else {
88 return -ENODATA;
89 }
90 break;
91 case SENSOR_CHAN_MAGN_X:
92 if (edata->has_magn_x) {
93 struct sensor_q31_data *out = data_out;
94
95 out->header.base_timestamp_ns = edata->header.timestamp;
96 out->header.reading_count = 1;
97 out->readings[0].value = data->magn_x * MMC56X3_MAGN_CONV_Q5_26_20B;
98 out->shift = MMC56X3_MAGN_SHIFT;
99 } else {
100 return -ENODATA;
101 }
102 break;
103 case SENSOR_CHAN_MAGN_Y:
104 if (edata->has_magn_y) {
105 struct sensor_q31_data *out = data_out;
106
107 out->header.base_timestamp_ns = edata->header.timestamp;
108 out->header.reading_count = 1;
109 out->readings[0].value = data->magn_y * MMC56X3_MAGN_CONV_Q5_26_20B;
110 out->shift = MMC56X3_MAGN_SHIFT;
111 } else {
112 return -ENODATA;
113 }
114 break;
115 case SENSOR_CHAN_MAGN_Z:
116 if (edata->has_magn_z) {
117 struct sensor_q31_data *out = data_out;
118
119 out->header.base_timestamp_ns = edata->header.timestamp;
120 out->header.reading_count = 1;
121 out->readings[0].value = data->magn_z * MMC56X3_MAGN_CONV_Q5_26_20B;
122 out->shift = MMC56X3_MAGN_SHIFT;
123 } else {
124 return -ENODATA;
125 }
126 break;
127 case SENSOR_CHAN_MAGN_XYZ: {
128 if (edata->has_magn_x && edata->has_magn_y && edata->has_magn_z) {
129 struct sensor_three_axis_data *out_3 = data_out;
130
131 out_3->header.base_timestamp_ns = edata->header.timestamp;
132 out_3->header.reading_count = 1;
133 out_3->shift = MMC56X3_MAGN_SHIFT;
134
135 out_3->readings[0].v[0] = data->magn_x * MMC56X3_MAGN_CONV_Q5_26_20B;
136 out_3->readings[0].v[1] = data->magn_y * MMC56X3_MAGN_CONV_Q5_26_20B;
137 out_3->readings[0].v[2] = data->magn_z * MMC56X3_MAGN_CONV_Q5_26_20B;
138 } else {
139 return -ENODATA;
140 }
141 break;
142 }
143 default:
144 return -EINVAL;
145 }
146
147 *fit = 1;
148 return 1;
149 }
150
151 SENSOR_DECODER_API_DT_DEFINE() = {
152 .get_frame_count = mmc56x3_decoder_get_frame_count,
153 .get_size_info = mmc56x3_decoder_get_size_info,
154 .decode = mmc56x3_decoder_decode,
155 };
156
mmc56x3_get_decoder(const struct device * dev,const struct sensor_decoder_api ** decoder)157 int mmc56x3_get_decoder(const struct device *dev, const struct sensor_decoder_api **decoder)
158 {
159 ARG_UNUSED(dev);
160 *decoder = &SENSOR_DECODER_NAME();
161
162 return 0;
163 }
164