1 /* sensor_bmm150.h - header file for BMM150 Geomagnetic sensor driver */
2 
3 /*
4  * Copyright (c) 2017 Intel Corporation
5  * Copyright (c) 2023 FTP Technologies
6  *
7  * SPDX-License-Identifier: Apache-2.0
8  */
9 
10 #ifndef ZEPHYR_DRIVERS_SENSOR_BMM150_BMM150_H_
11 #define ZEPHYR_DRIVERS_SENSOR_BMM150_BMM150_H_
12 
13 #include <zephyr/types.h>
14 #include <zephyr/device.h>
15 #include <zephyr/devicetree.h>
16 #include <zephyr/drivers/spi.h>
17 #include <zephyr/drivers/i2c.h>
18 
19 #define DT_DRV_COMPAT bosch_bmm150
20 
21 #define BMM150_BUS_SPI DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
22 #define BMM150_BUS_I2C DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
23 
24 union bmm150_bus {
25 #if BMM150_BUS_SPI
26 	struct spi_dt_spec spi;
27 #endif
28 #if BMM150_BUS_I2C
29 	struct i2c_dt_spec i2c;
30 #endif
31 };
32 
33 typedef int (*bmm150_bus_check_fn)(const union bmm150_bus *bus);
34 typedef int (*bmm150_reg_read_fn)(const union bmm150_bus *bus,
35 				  uint8_t start, uint8_t *buf, int size);
36 typedef int (*bmm150_reg_write_fn)(const union bmm150_bus *bus,
37 				   uint8_t reg, uint8_t val);
38 
39 struct bmm150_bus_io {
40 	bmm150_bus_check_fn check;
41 	bmm150_reg_read_fn read;
42 	bmm150_reg_write_fn write;
43 };
44 
45 #if BMM150_BUS_SPI
46 #define BMM150_SPI_OPERATION (SPI_WORD_SET(8) | SPI_TRANSFER_MSB |	\
47 			      SPI_MODE_CPOL | SPI_MODE_CPHA)
48 extern const struct bmm150_bus_io bmm150_bus_io_spi;
49 #endif
50 
51 #if BMM150_BUS_I2C
52 extern const struct bmm150_bus_io bmm150_bus_io_i2c;
53 #endif
54 
55 #include <zephyr/types.h>
56 #include <zephyr/drivers/i2c.h>
57 #include <stdint.h>
58 #include <zephyr/sys/util.h>
59 
60 #include <zephyr/kernel.h>
61 #include <zephyr/device.h>
62 #include <zephyr/drivers/sensor.h>
63 #include <zephyr/pm/device.h>
64 #include <zephyr/sys/byteorder.h>
65 #include <zephyr/sys/__assert.h>
66 #include <zephyr/drivers/gpio.h>
67 
68 #define BMM150_REG_CHIP_ID         0x40
69 #define BMM150_CHIP_ID_VAL         0x32
70 
71 #define BMM150_REG_X_L             0x42
72 #define BMM150_REG_X_M             0x43
73 #define BMM150_REG_Y_L             0x44
74 #define BMM150_REG_Y_M             0x45
75 #define BMM150_SHIFT_XY_L          3
76 #define BMM150_REG_Z_L             0x46
77 #define BMM150_REG_Z_M             0x47
78 #define BMM150_SHIFT_Z_L           1
79 #define BMM150_REG_RHALL_L         0x48
80 #define BMM150_REG_RHALL_M         0x49
81 #define BMM150_SHIFT_RHALL_L       2
82 
83 #define BMM150_REG_INT_STATUS      0x4A
84 
85 #define BMM150_REG_POWER           0x4B
86 #define BMM150_MASK_POWER_CTL      BIT(0)
87 #define BMM150_MASK_SOFT_RESET     (BIT(7) | BIT(1))
88 #define BMM150_SOFT_RESET          BMM150_MASK_SOFT_RESET
89 
90 #define BMM150_REG_OPMODE_ODR      0x4C
91 #define BMM150_MASK_OPMODE         (BIT(2) | BIT(1))
92 #define BMM150_SHIFT_OPMODE        1
93 #define BMM150_MODE_NORMAL         0x00
94 #define BMM150_MODE_FORCED         0x01
95 #define BMM150_MODE_SLEEP          0x03
96 #define BMM150_MASK_ODR            (BIT(5) | BIT(4) | BIT(3))
97 #define BMM150_SHIFT_ODR           3
98 
99 #define BMM150_REG_LOW_THRESH      0x4F
100 #define BMM150_REG_HIGH_THRESH     0x50
101 #define BMM150_REG_REP_XY          0x51
102 #define BMM150_REG_REP_Z           0x52
103 #define BMM150_REG_REP_DATAMASK    0xFF
104 
105 #define BMM150_REG_TRIM_START      0x5D
106 #define BMM150_REG_TRIM_END        0x71
107 
108 #define BMM150_XY_OVERFLOW_VAL     -4096
109 #define BMM150_Z_OVERFLOW_VAL      -16384
110 
111 #define BMM150_REGVAL_TO_REPXY(regval)     (((regval) * 2) + 1)
112 #define BMM150_REGVAL_TO_REPZ(regval)      ((regval) + 1)
113 #define BMM150_REPXY_TO_REGVAL(rep)        (((rep) - 1) / 2)
114 #define BMM150_REPZ_TO_REGVAL(rep)         BMM150_REPXY_TO_REGVAL(rep)
115 
116 #define BMM150_REG_INT                     0x4D
117 
118 #define BMM150_REG_INT_DRDY                0x4E
119 #define BMM150_MASK_DRDY_EN                BIT(7)
120 #define BMM150_SHIFT_DRDY_EN               7
121 #define BMM150_DRDY_INT3                   BIT(6)
122 #define BMM150_MASK_DRDY_Z_EN              BIT(5)
123 #define BMM150_MASK_DRDY_Y_EN              BIT(4)
124 #define BMM150_MASK_DRDY_X_EN              BIT(3)
125 #define BMM150_MASK_DRDY_DR_POLARITY       BIT(2)
126 #define BMM150_SHIFT_DRDY_DR_POLARITY      2
127 #define BMM150_MASK_DRDY_LATCHING          BIT(1)
128 #define BMM150_MASK_DRDY_INT3_POLARITY     BIT(0)
129 
130 #if defined(CONFIG_BMM150_SAMPLING_REP_XY) || \
131 	defined(CONFIG_BMM150_SAMPLING_REP_Z)
132 	#define BMM150_SET_ATTR_REP
133 #endif
134 
135 #if defined(CONFIG_BMM150_SAMPLING_RATE_RUNTIME) || \
136 	defined(BMM150_MAGN_SET_ATTR_REP)
137 	#define BMM150_MAGN_SET_ATTR
138 #endif
139 
140 struct bmm150_trim_regs {
141 	int8_t x1;
142 	int8_t y1;
143 	uint16_t reserved1;
144 	uint8_t reserved2;
145 	int16_t z4;
146 	int8_t x2;
147 	int8_t y2;
148 	uint16_t reserved3;
149 	int16_t z2;
150 	uint16_t z1;
151 	uint16_t xyz1;
152 	int16_t z3;
153 	int8_t xy2;
154 	uint8_t xy1;
155 } __packed;
156 
157 struct bmm150_config {
158 	union bmm150_bus bus;
159 	const struct bmm150_bus_io *bus_io;
160 
161 #ifdef CONFIG_BMM150_TRIGGER
162 	struct gpio_dt_spec drdy_int;
163 #endif
164 };
165 
166 struct bmm150_data {
167 	struct bmm150_trim_regs tregs;
168 	int rep_xy, rep_z, odr, max_odr;
169 	int sample_x, sample_y, sample_z;
170 
171 #if defined(CONFIG_BMM150_TRIGGER)
172 	struct gpio_callback gpio_cb;
173 #endif
174 
175 #ifdef CONFIG_BMM150_TRIGGER_OWN_THREAD
176 	struct k_sem sem;
177 #endif
178 
179 #ifdef CONFIG_BMM150_TRIGGER_GLOBAL_THREAD
180 	struct k_work work;
181 #endif
182 
183 #if defined(CONFIG_BMM150_TRIGGER_GLOBAL_THREAD) || \
184 	defined(CONFIG_BMM150_TRIGGER_DIRECT)
185 	const struct device *dev;
186 #endif
187 
188 #ifdef CONFIG_BMM150_TRIGGER
189 	const struct sensor_trigger *drdy_trigger;
190 	sensor_trigger_handler_t drdy_handler;
191 #endif /* CONFIG_BMM150_TRIGGER */
192 };
193 
194 enum bmm150_axis {
195 	BMM150_AXIS_X,
196 	BMM150_AXIS_Y,
197 	BMM150_AXIS_Z,
198 	BMM150_RHALL,
199 	BMM150_AXIS_XYZ_MAX = BMM150_RHALL,
200 	BMM150_AXIS_XYZR_MAX
201 };
202 
203 enum bmm150_presets {
204 	BMM150_LOW_POWER_PRESET,
205 	BMM150_REGULAR_PRESET,
206 	BMM150_ENHANCED_REGULAR_PRESET,
207 	BMM150_HIGH_ACCURACY_PRESET
208 };
209 
210 #if defined(CONFIG_BMM150_PRESET_LOW_POWER)
211 	#define BMM150_DEFAULT_PRESET BMM150_LOW_POWER_PRESET
212 #elif defined(CONFIG_BMM150_PRESET_REGULAR)
213 	#define BMM150_DEFAULT_PRESET BMM150_REGULAR_PRESET
214 #elif defined(CONFIG_BMM150_PRESET_ENHANCED_REGULAR)
215 	#define BMM150_DEFAULT_PRESET BMM150_ENHANCED_REGULAR_PRESET
216 #elif defined(CONFIG_BMM150_PRESET_HIGH_ACCURACY)
217 	#define BMM150_DEFAULT_PRESET BMM150_HIGH_ACCURACY_PRESET
218 #endif
219 
220 /* Power On Reset time - from OFF to Suspend (Max) */
221 #define BMM150_POR_TIME K_MSEC(1)
222 
223 /* Start-Up Time - from suspend to sleep (Max) */
224 #define BMM150_START_UP_TIME K_MSEC(3)
225 
226 int bmm150_trigger_mode_init(const struct device *dev);
227 
228 int bmm150_trigger_set(const struct device *dev,
229 		       const struct sensor_trigger *trig,
230 		       sensor_trigger_handler_t handler);
231 
232 int bmm150_reg_update_byte(const struct device *dev, uint8_t reg,
233 			   uint8_t mask, uint8_t value);
234 
235 #endif /* __SENSOR_BMM150_H__ */
236