1 /*
2 * Copyright (c) 2023 Michal Morsisko
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT ti_tmag5170
8
9 #include <zephyr/drivers/sensor.h>
10 #include <zephyr/logging/log.h>
11 #include <zephyr/kernel.h>
12 #include <zephyr/devicetree.h>
13 #include <zephyr/pm/device.h>
14 #include <zephyr/sys/byteorder.h>
15 #include <zephyr/sys/__assert.h>
16
17 #if defined(CONFIG_TMAG5170_CRC)
18 #include <zephyr/sys/crc.h>
19 #endif
20
21 #include "tmag5170.h"
22
23 #define TMAG5170_REG_DEVICE_CONFIG 0x0U
24 #define TMAG5170_REG_SENSOR_CONFIG 0x1U
25 #define TMAG5170_REG_SYSTEM_CONFIG 0x2U
26 #define TMAG5170_REG_ALERT_CONFIG 0x3U
27 #define TMAG5170_REG_X_THRX_CONFIG 0x4U
28 #define TMAG5170_REG_Y_THRX_CONFIG 0x5U
29 #define TMAG5170_REG_Z_THRX_CONFIG 0x6U
30 #define TMAG5170_REG_T_THRX_CONFIG 0x7U
31 #define TMAG5170_REG_CONV_STATUS 0x8U
32 #define TMAG5170_REG_X_CH_RESULT 0x9U
33 #define TMAG5170_REG_Y_CH_RESULT 0xAU
34 #define TMAG5170_REG_Z_CH_RESULT 0xBU
35 #define TMAG5170_REG_TEMP_RESULT 0xCU
36 #define TMAG5170_REG_AFE_STATUS 0xDU
37 #define TMAG5170_REG_SYS_STATUS 0xEU
38 #define TMAG5170_REG_TEST_CONFIG 0xFU
39 #define TMAG5170_REG_OSC_MONITOR 0x10U
40 #define TMAG5170_REG_MAG_GAIN_CONFIG 0x11U
41 #define TMAG5170_REG_MAG_OFFSET_CONFIG 0x12U
42 #define TMAG5170_REG_ANGLE_RESULT 0x13U
43 #define TMAG5170_REG_MAGNITUDE_RESULT 0x14U
44
45 #define TMAG5170_CONV_AVG_POS 12U
46 #define TMAG5170_CONV_AVG_MASK (BIT_MASK(3U) << TMAG5170_CONV_AVG_POS)
47 #define TMAG5170_CONV_AVG_SET(value) (((value) << TMAG5170_CONV_AVG_POS) &\
48 TMAG5170_CONV_AVG_MASK)
49
50 #define TMAG5170_MAG_TEMPCO_POS 8U
51 #define TMAG5170_MAG_TEMPCO_MASK (BIT_MASK(2U) << TMAG5170_MAG_TEMPCO_POS)
52 #define TMAG5170_MAG_TEMPCO_SET(value) (((value) << TMAG5170_MAG_TEMPCO_POS) &\
53 TMAG5170_MAG_TEMPCO_MASK)
54
55 #define TMAG5170_OPERATING_MODE_POS 4U
56 #define TMAG5170_OPERATING_MODE_MASK (BIT_MASK(3U) << TMAG5170_OPERATING_MODE_POS)
57 #define TMAG5170_OPERATING_MODE_SET(value) (((value) << TMAG5170_OPERATING_MODE_POS) &\
58 TMAG5170_OPERATING_MODE_MASK)
59
60 #define TMAG5170_T_CH_EN_POS 3U
61 #define TMAG5170_T_CH_EN_MASK (BIT_MASK(1U) << TMAG5170_T_CH_EN_POS)
62 #define TMAG5170_T_CH_EN_SET(value) (((value) << TMAG5170_T_CH_EN_POS) &\
63 TMAG5170_T_CH_EN_MASK)
64
65 #define TMAG5170_T_RATE_POS 2U
66 #define TMAG5170_T_RATE_MASK (BIT_MASK(1U) << TMAG5170_T_RATE_POS)
67 #define TMAG5170_T_RATE_SET(value) (((value) << TMAG5170_T_RATE_POS) &\
68 TMAG5170_T_RATE_MASK)
69
70 #define TMAG5170_ANGLE_EN_POS 14U
71 #define TMAG5170_ANGLE_EN_MASK (BIT_MASK(2U) << TMAG5170_ANGLE_EN_POS)
72 #define TMAG5170_ANGLE_EN_SET(value) (((value) << TMAG5170_ANGLE_EN_POS) &\
73 TMAG5170_ANGLE_EN_MASK)
74
75 #define TMAG5170_SLEEPTIME_POS 10U
76 #define TMAG5170_SLEEPTIME_MASK (BIT_MASK(4U) << TMAG5170_SLEEPTIME_POS)
77 #define TMAG5170_SLEEPTIME_SET(value) (((value) << TMAG5170_SLEEPTIME_POS) &\
78 TMAG5170_SLEEPTIME_MASK)
79
80 #define TMAG5170_MAG_CH_EN_POS 6U
81 #define TMAG5170_MAG_CH_EN_MASK (BIT_MASK(4U) << TMAG5170_MAG_CH_EN_POS)
82 #define TMAG5170_MAG_CH_EN_SET(value) (((value) << TMAG5170_MAG_CH_EN_POS) &\
83 TMAG5170_MAG_CH_EN_MASK)
84
85 #define TMAG5170_Z_RANGE_POS 4U
86 #define TMAG5170_Z_RANGE_MASK (BIT_MASK(2U) << TMAG5170_Z_RANGE_POS)
87 #define TMAG5170_Z_RANGE_SET(value) (((value) << TMAG5170_Z_RANGE_POS) &\
88 TMAG5170_Z_RANGE_MASK)
89
90 #define TMAG5170_Y_RANGE_POS 2U
91 #define TMAG5170_Y_RANGE_MASK (BIT_MASK(2U) << TMAG5170_Y_RANGE_POS)
92 #define TMAG5170_Y_RANGE_SET(value) (((value) << TMAG5170_Y_RANGE_POS) &\
93 TMAG5170_Y_RANGE_MASK)
94
95 #define TMAG5170_X_RANGE_POS 0U
96 #define TMAG5170_X_RANGE_MASK (BIT_MASK(2U) << TMAG5170_X_RANGE_POS)
97 #define TMAG5170_X_RANGE_SET(value) (((value) << TMAG5170_X_RANGE_POS) &\
98 TMAG5170_X_RANGE_MASK)
99
100 #define TMAG5170_RSLT_ALRT_POS 8U
101 #define TMAG5170_RSLT_ALRT_MASK (BIT_MASK(1U) << TMAG5170_RSLT_ALRT_POS)
102 #define TMAG5170_RSLT_ALRT_SET(value) (((value) << TMAG5170_RSLT_ALRT_POS) &\
103 TMAG5170_RSLT_ALRT_MASK)
104
105 #define TMAG5170_VER_POS 4U
106 #define TMAG5170_VER_MASK (BIT_MASK(2U) << TMAG5170_VER_POS)
107 #define TMAG5170_VER_GET(value) (((value) & TMAG5170_VER_MASK) >> TMAG5170_VER_POS)
108
109 #define TMAG5170_A1_REV 0x0U
110 #define TMAG5170_A2_REV 0x1U
111
112 #define TMAG5170_MAX_RANGE_50MT_IDX 0x0U
113 #define TMAG5170_MAX_RANGE_25MT_IDX 0x1U
114 #define TMAG5170_MAX_RANGE_100MT_IDX 0x2U
115 #define TMAG5170_MAX_RANGE_EXTEND_FACTOR 0x3U
116
117 #define TMAG5170_CONFIGURATION_MODE 0x0U
118 #define TMAG5170_STAND_BY_MODE 0x1U
119 #define TMAG5170_ACTIVE_TRIGGER_MODE 0x3U
120 #define TMAG5170_SLEEP_MODE 0x5U
121 #define TMAG5170_DEEP_SLEEP_MODE 0x6U
122
123 #define TMAG5170_MT_TO_GAUSS_RATIO 10U
124 #define TMAG5170_T_SENS_T0 25U
125 #define TMAG5170_T_ADC_T0 17522U
126 #define TMAG5170_T_ADC_RES 60U
127
128 #define TMAG5170_CMD_TRIGGER_CONVERSION BIT(0U)
129
130 #define TMAG5170_CRC_SEED 0xFU
131 #define TMAG5170_CRC_POLY 0x3U
132 #define TMAG5170_SPI_BUFFER_LEN 4U
133 #define TMAG5170_SET_CRC(buf, crc) ((uint8_t *)(buf))[3] |= (crc & 0x0F)
134 #define TMAG5170_ZERO_CRC(buf) ((uint8_t *)(buf))[3] &= 0xF0
135 #define TMAG5170_GET_CRC(buf) ((uint8_t *)(buf))[3] & 0x0F
136
137 LOG_MODULE_REGISTER(TMAG5170, CONFIG_SENSOR_LOG_LEVEL);
138
tmag5170_transmit_raw(const struct tmag5170_dev_config * config,uint8_t * buffer_tx,uint8_t * buffer_rx)139 static int tmag5170_transmit_raw(const struct tmag5170_dev_config *config,
140 uint8_t *buffer_tx,
141 uint8_t *buffer_rx)
142 {
143 const struct spi_buf tx_buf = {
144 .buf = buffer_tx,
145 .len = TMAG5170_SPI_BUFFER_LEN,
146 };
147
148 const struct spi_buf_set tx = {
149 .buffers = &tx_buf,
150 .count = 1
151 };
152
153 const struct spi_buf rx_buf = {
154 .buf = buffer_rx,
155 .len = TMAG5170_SPI_BUFFER_LEN,
156 };
157
158 const struct spi_buf_set rx = {
159 .buffers = &rx_buf,
160 .count = 1
161 };
162
163 int ret = spi_transceive_dt(&config->bus, &tx, &rx);
164
165 return ret;
166 }
167
tmag5170_transmit(const struct device * dev,uint8_t * buffer_tx,uint8_t * buffer_rx)168 static int tmag5170_transmit(const struct device *dev, uint8_t *buffer_tx, uint8_t *buffer_rx)
169 {
170 #if defined(CONFIG_TMAG5170_CRC)
171 TMAG5170_ZERO_CRC(buffer_tx);
172 uint8_t crc = crc4_ti(TMAG5170_CRC_SEED, buffer_tx, TMAG5170_SPI_BUFFER_LEN);
173
174 TMAG5170_SET_CRC(buffer_tx, crc);
175 #endif
176 int ret = tmag5170_transmit_raw(dev->config, buffer_tx, buffer_rx);
177 #if defined(CONFIG_TMAG5170_CRC)
178 if (buffer_rx != NULL && ret == 0) {
179 uint8_t read_crc = TMAG5170_GET_CRC(buffer_rx);
180
181 TMAG5170_ZERO_CRC(buffer_rx);
182 crc = crc4_ti(TMAG5170_CRC_SEED, buffer_rx, TMAG5170_SPI_BUFFER_LEN);
183 if (read_crc != crc) {
184 return -EIO;
185 }
186 }
187 #endif
188
189 return ret;
190 }
191
tmag5170_write_register(const struct device * dev,uint32_t reg,uint16_t data)192 static int tmag5170_write_register(const struct device *dev, uint32_t reg, uint16_t data)
193 {
194 uint8_t buffer_tx[4] = { reg, (data >> 8) & 0xFF, data & 0xFF, 0x00U };
195
196 return tmag5170_transmit(dev, buffer_tx, NULL);
197 }
198
tmag5170_read_register(const struct device * dev,uint32_t reg,uint16_t * output,uint8_t cmd)199 static int tmag5170_read_register(const struct device *dev,
200 uint32_t reg,
201 uint16_t *output,
202 uint8_t cmd)
203 {
204 uint8_t buffer_tx[4] = { BIT(7) | reg, 0x00U, 0x00U, (cmd & BIT_MASK(4U)) << 4U };
205 uint8_t buffer_rx[4] = { 0x00U };
206
207 int ret = tmag5170_transmit(dev, buffer_tx, buffer_rx);
208
209 *output = (buffer_rx[1] << 8) | buffer_rx[2];
210
211 return ret;
212 }
213
tmag5170_convert_magn_reading_to_gauss(struct sensor_value * output,uint16_t chan_reading,uint8_t chan_range,uint8_t chip_revision)214 static int tmag5170_convert_magn_reading_to_gauss(struct sensor_value *output,
215 uint16_t chan_reading,
216 uint8_t chan_range,
217 uint8_t chip_revision)
218 {
219 uint16_t max_range_mt = 0U;
220
221 if (chan_range == TMAG5170_MAX_RANGE_50MT_IDX) {
222 max_range_mt = 50U;
223 } else if (chan_range == TMAG5170_MAX_RANGE_25MT_IDX) {
224 max_range_mt = 25U;
225 } else if (chan_range == TMAG5170_MAX_RANGE_100MT_IDX) {
226 max_range_mt = 100U;
227 } else {
228 return -ENOTSUP;
229 }
230
231 if (chip_revision == TMAG5170_A2_REV) {
232 max_range_mt *= TMAG5170_MAX_RANGE_EXTEND_FACTOR;
233 }
234
235 max_range_mt *= 2U;
236
237 /* The sensor returns data in mT, we need to convert it to Gauss */
238 uint32_t max_range_gauss = max_range_mt * TMAG5170_MT_TO_GAUSS_RATIO;
239
240 /* Convert from 2's complementary system */
241 int64_t result = chan_reading - ((chan_reading & 0x8000) << 1);
242
243 result *= max_range_gauss;
244
245 /* Scale to increase accuracy */
246 result *= 100000;
247
248 /* Divide as it is shown in datasheet */
249 result /= 65536;
250
251 /* Remove scale from the final result */
252 output->val1 = result / 100000;
253 output->val2 = result % 100000;
254
255 return 0;
256 }
257
tmag5170_convert_temp_reading_to_celsius(struct sensor_value * output,uint16_t chan_reading)258 static void tmag5170_convert_temp_reading_to_celsius(struct sensor_value *output,
259 uint16_t chan_reading)
260 {
261 int32_t result = chan_reading - TMAG5170_T_ADC_T0;
262
263 result = (TMAG5170_T_SENS_T0 * 100000) + (100000 * result / (int32_t)TMAG5170_T_ADC_RES);
264
265 output->val1 = result / 100000;
266 output->val2 = (result % 100000) * 10;
267 }
268
tmag5170_covert_angle_reading_to_degrees(struct sensor_value * output,uint16_t chan_reading)269 static void tmag5170_covert_angle_reading_to_degrees(struct sensor_value *output,
270 uint16_t chan_reading)
271 {
272 /* 12 MSBs store the integer part of the result,
273 * 4 LSBs store the fractional part of the result
274 */
275 output->val1 = chan_reading >> 4;
276 output->val2 = ((chan_reading & 0xF) * 1000000) / 16;
277 }
278
tmag5170_sample_fetch(const struct device * dev,enum sensor_channel chan)279 static int tmag5170_sample_fetch(const struct device *dev,
280 enum sensor_channel chan)
281 {
282 const struct tmag5170_dev_config *cfg = dev->config;
283 struct tmag5170_data *drv_data = dev->data;
284 int ret = 0;
285
286 if (cfg->operating_mode == TMAG5170_STAND_BY_MODE ||
287 cfg->operating_mode == TMAG5170_ACTIVE_TRIGGER_MODE) {
288 uint16_t read_status;
289
290 tmag5170_read_register(dev,
291 TMAG5170_REG_SYS_STATUS,
292 &read_status,
293 TMAG5170_CMD_TRIGGER_CONVERSION);
294
295 /* Wait for the measurement to be ready.
296 * The waiting time will vary depending on the configuration
297 */
298 k_sleep(K_MSEC(5U));
299 }
300
301 switch (chan) {
302 case SENSOR_CHAN_MAGN_X:
303 ret = tmag5170_read_register(dev, TMAG5170_REG_X_CH_RESULT, &drv_data->x, 0U);
304 break;
305 case SENSOR_CHAN_MAGN_Y:
306 ret = tmag5170_read_register(dev, TMAG5170_REG_Y_CH_RESULT, &drv_data->y, 0U);
307 break;
308 case SENSOR_CHAN_MAGN_Z:
309 ret = tmag5170_read_register(dev, TMAG5170_REG_Z_CH_RESULT, &drv_data->z, 0U);
310 break;
311 case SENSOR_CHAN_MAGN_XYZ:
312 ret = tmag5170_read_register(dev, TMAG5170_REG_X_CH_RESULT, &drv_data->x, 0U);
313
314 if (ret == 0) {
315 ret = tmag5170_read_register(dev,
316 TMAG5170_REG_Y_CH_RESULT,
317 &drv_data->y,
318 0U);
319 }
320 if (ret == 0) {
321 ret = tmag5170_read_register(dev,
322 TMAG5170_REG_Z_CH_RESULT,
323 &drv_data->z,
324 0U);
325 }
326 break;
327 case SENSOR_CHAN_ROTATION:
328 ret = tmag5170_read_register(dev,
329 TMAG5170_REG_ANGLE_RESULT,
330 &drv_data->angle,
331 0U);
332 break;
333 case SENSOR_CHAN_AMBIENT_TEMP:
334 ret = tmag5170_read_register(dev,
335 TMAG5170_REG_TEMP_RESULT,
336 &drv_data->temperature,
337 0U);
338 break;
339 case SENSOR_CHAN_ALL:
340 ret = tmag5170_read_register(dev,
341 TMAG5170_REG_TEMP_RESULT,
342 &drv_data->temperature,
343 0U);
344
345 if (ret == 0) {
346 ret = tmag5170_read_register(dev,
347 TMAG5170_REG_ANGLE_RESULT,
348 &drv_data->angle,
349 0U);
350 }
351
352 if (ret == 0) {
353 ret = tmag5170_read_register(dev,
354 TMAG5170_REG_X_CH_RESULT,
355 &drv_data->x,
356 0U);
357 }
358
359 if (ret == 0) {
360 ret = tmag5170_read_register(dev,
361 TMAG5170_REG_Y_CH_RESULT,
362 &drv_data->y,
363 0U);
364 }
365
366 if (ret == 0) {
367 ret = tmag5170_read_register(dev,
368 TMAG5170_REG_Z_CH_RESULT,
369 &drv_data->z,
370 0U);
371 }
372
373 break;
374 default:
375 ret = -ENOTSUP;
376 break;
377 }
378
379 return ret;
380 }
381
tmag5170_channel_get(const struct device * dev,enum sensor_channel chan,struct sensor_value * val)382 static int tmag5170_channel_get(const struct device *dev,
383 enum sensor_channel chan,
384 struct sensor_value *val)
385 {
386 const struct tmag5170_dev_config *cfg = dev->config;
387 struct tmag5170_data *drv_data = dev->data;
388 int ret = 0;
389
390 switch (chan) {
391 case SENSOR_CHAN_MAGN_XYZ:
392 ret = tmag5170_convert_magn_reading_to_gauss(val,
393 drv_data->x,
394 cfg->x_range,
395 drv_data->chip_revision);
396
397 if (ret == 0) {
398 ret = tmag5170_convert_magn_reading_to_gauss(val + 1,
399 drv_data->y,
400 cfg->y_range,
401 drv_data->chip_revision);
402 }
403
404 if (ret == 0) {
405 ret = tmag5170_convert_magn_reading_to_gauss(val + 2,
406 drv_data->z,
407 cfg->z_range,
408 drv_data->chip_revision);
409 }
410 break;
411 case SENSOR_CHAN_MAGN_X:
412 ret = tmag5170_convert_magn_reading_to_gauss(val,
413 drv_data->x,
414 cfg->x_range,
415 drv_data->chip_revision);
416 break;
417 case SENSOR_CHAN_MAGN_Y:
418 ret = tmag5170_convert_magn_reading_to_gauss(val,
419 drv_data->y,
420 cfg->y_range,
421 drv_data->chip_revision);
422 break;
423 case SENSOR_CHAN_MAGN_Z:
424 ret = tmag5170_convert_magn_reading_to_gauss(val,
425 drv_data->z,
426 cfg->z_range,
427 drv_data->chip_revision);
428 break;
429 case SENSOR_CHAN_ROTATION:
430 tmag5170_covert_angle_reading_to_degrees(val, drv_data->angle);
431 break;
432 case SENSOR_CHAN_AMBIENT_TEMP:
433 tmag5170_convert_temp_reading_to_celsius(val, drv_data->temperature);
434 break;
435 default:
436 ret = -ENOTSUP;
437 break;
438 }
439
440 return ret;
441 }
442
tmag5170_init_registers(const struct device * dev)443 static int tmag5170_init_registers(const struct device *dev)
444 {
445 const struct tmag5170_dev_config *cfg = dev->config;
446 struct tmag5170_data *drv_data = dev->data;
447 uint16_t test_cfg_reg = 0U;
448 int ret = 0;
449
450 #if !defined(CONFIG_TMAG5170_CRC)
451 const uint8_t disable_crc_packet[4] = { 0x0FU, 0x0U, 0x04U, 0x07U };
452
453 ret = tmag5170_transmit_raw(cfg, disable_crc_packet, NULL);
454 #endif
455 if (ret == 0) {
456 ret = tmag5170_read_register(dev, TMAG5170_REG_TEST_CONFIG, &test_cfg_reg, 0U);
457 }
458
459 if (ret == 0) {
460 drv_data->chip_revision = TMAG5170_VER_GET(test_cfg_reg);
461
462 ret = tmag5170_write_register(dev,
463 TMAG5170_REG_SENSOR_CONFIG,
464 TMAG5170_ANGLE_EN_SET(cfg->angle_measurement) |
465 TMAG5170_SLEEPTIME_SET(cfg->sleep_time) |
466 TMAG5170_MAG_CH_EN_SET(cfg->magnetic_channels) |
467 TMAG5170_Z_RANGE_SET(cfg->z_range) |
468 TMAG5170_Y_RANGE_SET(cfg->y_range) |
469 TMAG5170_X_RANGE_SET(cfg->x_range));
470 }
471
472 #if defined(CONFIG_TMAG5170_TRIGGER)
473 if (ret == 0) {
474 ret = tmag5170_write_register(dev,
475 TMAG5170_REG_ALERT_CONFIG,
476 TMAG5170_RSLT_ALRT_SET(1U));
477 }
478 #endif
479 if (ret == 0) {
480 ret = tmag5170_write_register(dev,
481 TMAG5170_REG_DEVICE_CONFIG,
482 TMAG5170_OPERATING_MODE_SET(cfg->operating_mode) |
483 TMAG5170_CONV_AVG_SET(cfg->oversampling) |
484 TMAG5170_MAG_TEMPCO_SET(cfg->magnet_type) |
485 TMAG5170_T_CH_EN_SET(cfg->tempeature_measurement) |
486 TMAG5170_T_RATE_SET(cfg->disable_temperature_oversampling));
487 }
488
489 return ret;
490 }
491
492 #ifdef CONFIG_PM_DEVICE
tmag5170_pm_action(const struct device * dev,enum pm_device_action action)493 static int tmag5170_pm_action(const struct device *dev,
494 enum pm_device_action action)
495 {
496 int ret_val = 0;
497
498 switch (action) {
499 case PM_DEVICE_ACTION_RESUME:
500 tmag5170_write_register(dev,
501 TMAG5170_REG_DEVICE_CONFIG,
502 TMAG5170_OPERATING_MODE_SET(TMAG5170_CONFIGURATION_MODE));
503 /* As per datasheet, waking up from deep-sleep can take up to 500us */
504 k_sleep(K_USEC(500));
505 ret_val = tmag5170_init_registers(dev);
506 break;
507 case PM_DEVICE_ACTION_SUSPEND:
508 ret_val = tmag5170_write_register(dev,
509 TMAG5170_REG_DEVICE_CONFIG,
510 TMAG5170_OPERATING_MODE_SET(TMAG5170_DEEP_SLEEP_MODE));
511 break;
512 default:
513 ret_val = -ENOTSUP;
514 }
515
516 return ret_val;
517 }
518 #endif /* CONFIG_PM_DEVICE */
519
520 static DEVICE_API(sensor, tmag5170_driver_api) = {
521 .sample_fetch = tmag5170_sample_fetch,
522 .channel_get = tmag5170_channel_get,
523 #if defined(CONFIG_TMAG5170_TRIGGER)
524 .trigger_set = tmag5170_trigger_set
525 #endif
526 };
527
tmag5170_init(const struct device * dev)528 static int tmag5170_init(const struct device *dev)
529 {
530 const struct tmag5170_dev_config *cfg = dev->config;
531 int ret = 0;
532
533 if (!spi_is_ready_dt(&cfg->bus)) {
534 LOG_ERR("SPI dev %s not ready", cfg->bus.bus->name);
535 return -ENODEV;
536 }
537
538 ret = tmag5170_init_registers(dev);
539 if (ret != 0) {
540 return ret;
541 }
542
543 #if defined(CONFIG_TMAG5170_TRIGGER)
544 if (cfg->int_gpio.port) {
545 ret = tmag5170_trigger_init(dev);
546 }
547 #endif
548
549 return ret;
550 }
551
552 #define DEFINE_TMAG5170(_num) \
553 static struct tmag5170_data tmag5170_data_##_num; \
554 static const struct tmag5170_dev_config tmag5170_config_##_num = { \
555 .bus = SPI_DT_SPEC_INST_GET(_num, \
556 SPI_OP_MODE_MASTER | \
557 SPI_TRANSFER_MSB | \
558 SPI_WORD_SET(32), \
559 0), \
560 .magnetic_channels = DT_INST_ENUM_IDX(_num, magnetic_channels), \
561 .x_range = DT_INST_ENUM_IDX(_num, x_range), \
562 .y_range = DT_INST_ENUM_IDX(_num, y_range), \
563 .z_range = DT_INST_ENUM_IDX(_num, z_range), \
564 .operating_mode = DT_INST_PROP(_num, operating_mode), \
565 .oversampling = DT_INST_ENUM_IDX(_num, oversampling), \
566 .tempeature_measurement = DT_INST_PROP(_num, enable_temperature_channel), \
567 .magnet_type = DT_INST_ENUM_IDX(_num, magnet_type), \
568 .angle_measurement = DT_INST_ENUM_IDX(_num, angle_measurement), \
569 .disable_temperature_oversampling = DT_INST_PROP(_num, \
570 disable_temperature_oversampling), \
571 .sleep_time = DT_INST_ENUM_IDX(_num, sleep_time), \
572 IF_ENABLED(CONFIG_TMAG5170_TRIGGER, \
573 (.int_gpio = GPIO_DT_SPEC_INST_GET_OR(_num, int_gpios, { 0 }),)) \
574 }; \
575 PM_DEVICE_DT_INST_DEFINE(_num, tmag5170_pm_action); \
576 \
577 SENSOR_DEVICE_DT_INST_DEFINE(_num, \
578 tmag5170_init, \
579 PM_DEVICE_DT_INST_GET(_num), \
580 &tmag5170_data_##_num, \
581 &tmag5170_config_##_num, \
582 POST_KERNEL, \
583 CONFIG_SENSOR_INIT_PRIORITY, \
584 &tmag5170_driver_api);
585
586 DT_INST_FOREACH_STATUS_OKAY(DEFINE_TMAG5170)
587