1 /* 2 * Copyright (c) 2024 Intel Corporation 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef ZEPHYR_DRIVERS_SENSOR_MMC56X3_MMC56X3_H_ 8 #define ZEPHYR_DRIVERS_SENSOR_MMC56X3_MMC56X3_H_ 9 10 #include <zephyr/types.h> 11 #include <zephyr/device.h> 12 #include <zephyr/devicetree.h> 13 #include <zephyr/drivers/i2c.h> 14 #include <zephyr/drivers/sensor.h> 15 #include <zephyr/rtio/rtio.h> 16 #include <zephyr/drivers/sensor/mmc56x3.h> 17 18 #define DT_DRV_COMPAT memsic_mmc56x3 19 20 #define MMC56X3_BUS_I2C DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) 21 22 union mmc56x3_bus { 23 struct i2c_dt_spec i2c; 24 }; 25 26 typedef int (*mmc56x3_bus_check_fn)(const union mmc56x3_bus *bus); 27 typedef int (*mmc56x3_reg_read_fn)(const union mmc56x3_bus *bus, uint8_t start, uint8_t *buf, 28 int size); 29 typedef int (*mmc56x3_reg_write_fn)(const union mmc56x3_bus *bus, uint8_t reg, uint8_t val); 30 typedef int (*mmc56x3_raw_read_fn)(const union mmc56x3_bus *bus, uint8_t *buf, size_t size); 31 typedef int (*mmc56x3_raw_write_fn)(const union mmc56x3_bus *bus, uint8_t *buf, size_t size); 32 33 struct mmc56x3_bus_io { 34 mmc56x3_bus_check_fn check; 35 mmc56x3_reg_read_fn read; 36 mmc56x3_reg_write_fn write; 37 mmc56x3_raw_read_fn raw_read; 38 mmc56x3_raw_write_fn raw_write; 39 }; 40 41 extern const struct mmc56x3_bus_io mmc56x3_bus_io_i2c; 42 43 #define MMC56X3_REG_TEMP 0x09 44 #define MMC56X3_CHIP_ID 0x10 45 #define MMC56X3_REG_STATUS 0x18 46 #define MMC56X3_REG_INTERNAL_ODR 0x1a 47 #define MMC56X3_REG_INTERNAL_CTRL_0 0x1b 48 #define MMC56X3_REG_INTERNAL_CTRL_1 0x1c 49 #define MMC56X3_REG_INTERNAL_CTRL_2 0x1d 50 #define MMC56X3_REG_ID 0x39 51 52 #define MMC56X3_CMD_RESET 0x10 53 #define MMC56X3_CMD_SET 0x08 54 #define MMC56X3_CMD_SW_RESET 0x80 55 #define MMC56X3_CMD_TAKE_MEAS_M 0x01 56 #define MMC56X3_CMD_TAKE_MEAS_T 0x02 57 #define MMC56X3_CMD_AUTO_SELF_RESET_EN 0x20 58 #define MMC56X3_CMD_CMM_FREQ_EN 0x80 59 #define MMC56X3_CMD_CMM_EN 0x10 60 #define MMC56X3_CMD_HPOWER 0x80 61 62 #define MMC56X3_STATUS_MEAS_M_DONE 0x80 63 #define MMC56X3_STATUS_MEAS_T_DONE 0x40 64 65 #define MMC56X3_REG_MAGN_X_OUT_0 0x00 66 /* Range is -30 to 30, sensitivity of raw 20-bit reading is 67 * 16384 = 1 Gauss. To convert raw reading to 68 * Q5.26 with range -32 to 32, 69 * reading * (1/16384) * pow(2, 31)/32 70 * = reading * 4096 71 */ 72 #define MMC56X3_MAGN_CONV_Q5_26_20B 4096 73 /* 1/16384 */ 74 #define MMC56X3_MAGN_GAUSS_RES 0.000061035 75 /* To convert reading to Q7.24 with range -128, 128, 76 * (BASE + reading * RES) * pow(2, 31)/128 77 * = BASE * pow(2, 31)/128 + reading * RES * pow(2, 31)/128 78 * CONV_BASE = BASE * pow(2, 31)/128 79 * CONV_RES = RES * pow(2, 31)/128 80 * = CONV_BASE + reading * CONV_RES 81 */ 82 #define MMC56X3_TEMP_BASE -75 83 #define MMC56X3_TEMP_RES 0.8 84 #define MMC56X3_TEMP_CONV_Q7_24_BASE -1258291200 85 #define MMC56X3_TEMP_CONV_Q7_24_RES 13421773 86 87 #define MMC56X3_MAGN_SHIFT 5 88 #define MMC56X3_TEMP_SHIFT 7 89 90 #ifdef __cplusplus 91 extern "C" { 92 #endif 93 94 struct mmc56x3_config { 95 uint16_t magn_odr; 96 bool bw0; 97 bool bw1; 98 bool auto_sr; 99 }; 100 101 struct mmc56x3_data { 102 struct mmc56x3_config config; 103 104 uint8_t ctrl0_cache; 105 uint8_t ctrl1_cache; 106 uint8_t ctrl2_cache; 107 108 uint32_t temp; 109 int32_t magn_x; 110 int32_t magn_y; 111 int32_t magn_z; 112 }; 113 114 struct mmc56x3_dev_config { 115 union mmc56x3_bus bus; 116 const struct mmc56x3_bus_io *bus_io; 117 }; 118 119 struct mmc56x3_decoder_header { 120 uint64_t timestamp; 121 } __attribute__((__packed__)); 122 123 struct mmc56x3_encoded_data { 124 struct mmc56x3_decoder_header header; 125 struct { 126 /** Set if `temp` has data */ 127 uint8_t has_temp: 1; 128 /** Set if `magn_x` has data */ 129 uint8_t has_magn_x: 1; 130 /** Set if `magn_y` has data */ 131 uint8_t has_magn_y: 1; 132 /** Set if `magn_z` has data */ 133 uint8_t has_magn_z: 1; 134 } __attribute__((__packed__)); 135 struct mmc56x3_data data; 136 }; 137 138 int mmc56x3_get_decoder(const struct device *dev, const struct sensor_decoder_api **decoder); 139 140 void mmc56x3_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe); 141 142 int mmc56x3_sample_fetch(const struct device *dev, enum sensor_channel chan); 143 144 int mmc56x3_sample_fetch_helper(const struct device *dev, enum sensor_channel chan, 145 struct mmc56x3_data *data); 146 147 #ifdef __cplusplus 148 } 149 #endif 150 151 #endif /* ZEPHYR_DRIVERS_SENSOR_MMC56X3_MMC56X3_H_ */ 152