1 /*
2  * Copyright (c) 2023 Google LLC
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 
6 #ifndef ZEPHYR_DRIVERS_SENSOR_AKM09918C_AKM09918C_H_
7 #define ZEPHYR_DRIVERS_SENSOR_AKM09918C_AKM09918C_H_
8 
9 #include <zephyr/device.h>
10 #include <zephyr/drivers/i2c.h>
11 #include <zephyr/drivers/sensor.h>
12 #include <zephyr/rtio/rtio.h>
13 
14 #include "akm09918c_reg.h"
15 
16 /* Time it takes to get a measurement in single-measure mode */
17 #define AKM09918C_MEASURE_TIME_US 9000
18 
19 /* Conversion values */
20 #define AKM09918C_MICRO_GAUSS_PER_BIT INT64_C(1500)
21 
22 /* Maximum and minimum raw register values for magnetometer data per datasheet */
23 #define AKM09918C_MAGN_MAX_DATA_REG (32752)
24 #define AKM09918C_MAGN_MIN_DATA_REG (-32752)
25 
26 /* Maximum and minimum magnetometer values in microgauss. +/-32752 is the maximum range of the
27  * data registers (slightly less than the range of int16). This works out to +/- 49,128,000 uGs
28  */
29 #define AKM09918C_MAGN_MAX_MICRO_GAUSS (AKM09918C_MAGN_MAX_DATA_REG * AKM09918C_MICRO_GAUSS_PER_BIT)
30 #define AKM09918C_MAGN_MIN_MICRO_GAUSS (AKM09918C_MAGN_MIN_DATA_REG * AKM09918C_MICRO_GAUSS_PER_BIT)
31 
32 struct akm09918c_data {
33 	int16_t x_sample;
34 	int16_t y_sample;
35 	int16_t z_sample;
36 	uint8_t mode;
37 };
38 
39 struct akm09918c_config {
40 	struct i2c_dt_spec i2c;
41 };
42 
akm09918c_hz_to_reg(const struct sensor_value * val)43 static inline uint8_t akm09918c_hz_to_reg(const struct sensor_value *val)
44 {
45 	if (val->val1 >= 100) {
46 		return AKM09918C_CNTL2_CONTINUOUS_4;
47 	} else if (val->val1 >= 50) {
48 		return AKM09918C_CNTL2_CONTINUOUS_3;
49 	} else if (val->val1 >= 20) {
50 		return AKM09918C_CNTL2_CONTINUOUS_2;
51 	} else if (val->val1 > 0) {
52 		return AKM09918C_CNTL2_CONTINUOUS_1;
53 	} else {
54 		return AKM09918C_CNTL2_PWR_DOWN;
55 	}
56 }
57 
akm09918c_reg_to_hz(uint8_t reg,struct sensor_value * val)58 static inline void akm09918c_reg_to_hz(uint8_t reg, struct sensor_value *val)
59 {
60 	val->val1 = 0;
61 	val->val2 = 0;
62 	switch (reg) {
63 	case AKM09918C_CNTL2_CONTINUOUS_1:
64 		val->val1 = 10;
65 		break;
66 	case AKM09918C_CNTL2_CONTINUOUS_2:
67 		val->val1 = 20;
68 		break;
69 	case AKM09918C_CNTL2_CONTINUOUS_3:
70 		val->val1 = 50;
71 		break;
72 	case AKM09918C_CNTL2_CONTINUOUS_4:
73 		val->val1 = 100;
74 		break;
75 	}
76 }
77 
78 /*
79  * RTIO types
80  */
81 
82 struct akm09918c_decoder_header {
83 	uint64_t timestamp;
84 } __attribute__((__packed__));
85 
86 struct akm09918c_encoded_data {
87 	struct akm09918c_decoder_header header;
88 	int16_t readings[3];
89 };
90 
91 int akm09918c_sample_fetch_helper(const struct device *dev, enum sensor_channel chan, int16_t *x,
92 				  int16_t *y, int16_t *z);
93 
94 int akm09918c_get_decoder(const struct device *dev, const struct sensor_decoder_api **decoder);
95 
96 int akm09918c_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe);
97 
98 #endif /* ZEPHYR_DRIVERS_SENSOR_AKM09918C_AKM09918C_H_ */
99