| /* |
| * Copyright (c) 2023 Michal Morsisko |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #define DT_DRV_COMPAT ti_tmag5170 |
| |
| #include <zephyr/drivers/sensor.h> |
| #include <zephyr/logging/log.h> |
| #include <zephyr/kernel.h> |
| #include <zephyr/devicetree.h> |
| #include <zephyr/pm/device.h> |
| #include <zephyr/sys/byteorder.h> |
| #include <zephyr/sys/__assert.h> |
| |
| #if defined(CONFIG_TMAG5170_CRC) |
| #include <zephyr/sys/crc.h> |
| #endif |
| |
| #include "tmag5170.h" |
| |
| #define TMAG5170_REG_DEVICE_CONFIG 0x0U |
| #define TMAG5170_REG_SENSOR_CONFIG 0x1U |
| #define TMAG5170_REG_SYSTEM_CONFIG 0x2U |
| #define TMAG5170_REG_ALERT_CONFIG 0x3U |
| #define TMAG5170_REG_X_THRX_CONFIG 0x4U |
| #define TMAG5170_REG_Y_THRX_CONFIG 0x5U |
| #define TMAG5170_REG_Z_THRX_CONFIG 0x6U |
| #define TMAG5170_REG_T_THRX_CONFIG 0x7U |
| #define TMAG5170_REG_CONV_STATUS 0x8U |
| #define TMAG5170_REG_X_CH_RESULT 0x9U |
| #define TMAG5170_REG_Y_CH_RESULT 0xAU |
| #define TMAG5170_REG_Z_CH_RESULT 0xBU |
| #define TMAG5170_REG_TEMP_RESULT 0xCU |
| #define TMAG5170_REG_AFE_STATUS 0xDU |
| #define TMAG5170_REG_SYS_STATUS 0xEU |
| #define TMAG5170_REG_TEST_CONFIG 0xFU |
| #define TMAG5170_REG_OSC_MONITOR 0x10U |
| #define TMAG5170_REG_MAG_GAIN_CONFIG 0x11U |
| #define TMAG5170_REG_MAG_OFFSET_CONFIG 0x12U |
| #define TMAG5170_REG_ANGLE_RESULT 0x13U |
| #define TMAG5170_REG_MAGNITUDE_RESULT 0x14U |
| |
| #define TMAG5170_CONV_AVG_POS 12U |
| #define TMAG5170_CONV_AVG_MASK (BIT_MASK(3U) << TMAG5170_CONV_AVG_POS) |
| #define TMAG5170_CONV_AVG_SET(value) (((value) << TMAG5170_CONV_AVG_POS) &\ |
| TMAG5170_CONV_AVG_MASK) |
| |
| #define TMAG5170_MAG_TEMPCO_POS 8U |
| #define TMAG5170_MAG_TEMPCO_MASK (BIT_MASK(2U) << TMAG5170_MAG_TEMPCO_POS) |
| #define TMAG5170_MAG_TEMPCO_SET(value) (((value) << TMAG5170_MAG_TEMPCO_POS) &\ |
| TMAG5170_MAG_TEMPCO_MASK) |
| |
| #define TMAG5170_OPERATING_MODE_POS 4U |
| #define TMAG5170_OPERATING_MODE_MASK (BIT_MASK(3U) << TMAG5170_OPERATING_MODE_POS) |
| #define TMAG5170_OPERATING_MODE_SET(value) (((value) << TMAG5170_OPERATING_MODE_POS) &\ |
| TMAG5170_OPERATING_MODE_MASK) |
| |
| #define TMAG5170_T_CH_EN_POS 3U |
| #define TMAG5170_T_CH_EN_MASK (BIT_MASK(1U) << TMAG5170_T_CH_EN_POS) |
| #define TMAG5170_T_CH_EN_SET(value) (((value) << TMAG5170_T_CH_EN_POS) &\ |
| TMAG5170_T_CH_EN_MASK) |
| |
| #define TMAG5170_T_RATE_POS 2U |
| #define TMAG5170_T_RATE_MASK (BIT_MASK(1U) << TMAG5170_T_RATE_POS) |
| #define TMAG5170_T_RATE_SET(value) (((value) << TMAG5170_T_RATE_POS) &\ |
| TMAG5170_T_RATE_MASK) |
| |
| #define TMAG5170_ANGLE_EN_POS 14U |
| #define TMAG5170_ANGLE_EN_MASK (BIT_MASK(2U) << TMAG5170_ANGLE_EN_POS) |
| #define TMAG5170_ANGLE_EN_SET(value) (((value) << TMAG5170_ANGLE_EN_POS) &\ |
| TMAG5170_ANGLE_EN_MASK) |
| |
| #define TMAG5170_SLEEPTIME_POS 10U |
| #define TMAG5170_SLEEPTIME_MASK (BIT_MASK(4U) << TMAG5170_SLEEPTIME_POS) |
| #define TMAG5170_SLEEPTIME_SET(value) (((value) << TMAG5170_SLEEPTIME_POS) &\ |
| TMAG5170_SLEEPTIME_MASK) |
| |
| #define TMAG5170_MAG_CH_EN_POS 6U |
| #define TMAG5170_MAG_CH_EN_MASK (BIT_MASK(4U) << TMAG5170_MAG_CH_EN_POS) |
| #define TMAG5170_MAG_CH_EN_SET(value) (((value) << TMAG5170_MAG_CH_EN_POS) &\ |
| TMAG5170_MAG_CH_EN_MASK) |
| |
| #define TMAG5170_Z_RANGE_POS 4U |
| #define TMAG5170_Z_RANGE_MASK (BIT_MASK(2U) << TMAG5170_Z_RANGE_POS) |
| #define TMAG5170_Z_RANGE_SET(value) (((value) << TMAG5170_Z_RANGE_POS) &\ |
| TMAG5170_Z_RANGE_MASK) |
| |
| #define TMAG5170_Y_RANGE_POS 2U |
| #define TMAG5170_Y_RANGE_MASK (BIT_MASK(2U) << TMAG5170_Y_RANGE_POS) |
| #define TMAG5170_Y_RANGE_SET(value) (((value) << TMAG5170_Y_RANGE_POS) &\ |
| TMAG5170_Y_RANGE_MASK) |
| |
| #define TMAG5170_X_RANGE_POS 0U |
| #define TMAG5170_X_RANGE_MASK (BIT_MASK(2U) << TMAG5170_X_RANGE_POS) |
| #define TMAG5170_X_RANGE_SET(value) (((value) << TMAG5170_X_RANGE_POS) &\ |
| TMAG5170_X_RANGE_MASK) |
| |
| #define TMAG5170_RSLT_ALRT_POS 8U |
| #define TMAG5170_RSLT_ALRT_MASK (BIT_MASK(1U) << TMAG5170_RSLT_ALRT_POS) |
| #define TMAG5170_RSLT_ALRT_SET(value) (((value) << TMAG5170_RSLT_ALRT_POS) &\ |
| TMAG5170_RSLT_ALRT_MASK) |
| |
| #define TMAG5170_VER_POS 4U |
| #define TMAG5170_VER_MASK (BIT_MASK(2U) << TMAG5170_VER_POS) |
| #define TMAG5170_VER_GET(value) (((value) & TMAG5170_VER_MASK) >> TMAG5170_VER_POS) |
| |
| #define TMAG5170_A1_REV 0x0U |
| #define TMAG5170_A2_REV 0x1U |
| |
| #define TMAG5170_MAX_RANGE_50MT_IDX 0x0U |
| #define TMAG5170_MAX_RANGE_25MT_IDX 0x1U |
| #define TMAG5170_MAX_RANGE_100MT_IDX 0x2U |
| #define TMAG5170_MAX_RANGE_EXTEND_FACTOR 0x3U |
| |
| #define TMAG5170_CONFIGURATION_MODE 0x0U |
| #define TMAG5170_STAND_BY_MODE 0x1U |
| #define TMAG5170_ACTIVE_TRIGGER_MODE 0x3U |
| #define TMAG5170_SLEEP_MODE 0x5U |
| #define TMAG5170_DEEP_SLEEP_MODE 0x6U |
| |
| #define TMAG5170_MT_TO_GAUSS_RATIO 10U |
| #define TMAG5170_T_SENS_T0 25U |
| #define TMAG5170_T_ADC_T0 17522U |
| #define TMAG5170_T_ADC_RES 60U |
| |
| #define TMAG5170_CMD_TRIGGER_CONVERSION BIT(0U) |
| |
| #define TMAG5170_CRC_SEED 0xFU |
| #define TMAG5170_CRC_POLY 0x3U |
| #define TMAG5170_SPI_BUFFER_LEN 4U |
| #define TMAG5170_SET_CRC(buf, crc) ((uint8_t *)(buf))[3] |= (crc & 0x0F) |
| #define TMAG5170_ZERO_CRC(buf) ((uint8_t *)(buf))[3] &= 0xF0 |
| #define TMAG5170_GET_CRC(buf) ((uint8_t *)(buf))[3] & 0x0F |
| |
| LOG_MODULE_REGISTER(TMAG5170, CONFIG_SENSOR_LOG_LEVEL); |
| |
| static int tmag5170_transmit_raw(const struct tmag5170_dev_config *config, |
| uint8_t *buffer_tx, |
| uint8_t *buffer_rx) |
| { |
| const struct spi_buf tx_buf = { |
| .buf = buffer_tx, |
| .len = TMAG5170_SPI_BUFFER_LEN, |
| }; |
| |
| const struct spi_buf_set tx = { |
| .buffers = &tx_buf, |
| .count = 1 |
| }; |
| |
| const struct spi_buf rx_buf = { |
| .buf = buffer_rx, |
| .len = TMAG5170_SPI_BUFFER_LEN, |
| }; |
| |
| const struct spi_buf_set rx = { |
| .buffers = &rx_buf, |
| .count = 1 |
| }; |
| |
| int ret = spi_transceive_dt(&config->bus, &tx, &rx); |
| |
| return ret; |
| } |
| |
| static int tmag5170_transmit(const struct device *dev, uint8_t *buffer_tx, uint8_t *buffer_rx) |
| { |
| #if defined(CONFIG_TMAG5170_CRC) |
| TMAG5170_ZERO_CRC(buffer_tx); |
| uint8_t crc = crc4_ti(TMAG5170_CRC_SEED, buffer_tx, TMAG5170_SPI_BUFFER_LEN); |
| |
| TMAG5170_SET_CRC(buffer_tx, crc); |
| #endif |
| int ret = tmag5170_transmit_raw(dev->config, buffer_tx, buffer_rx); |
| #if defined(CONFIG_TMAG5170_CRC) |
| if (buffer_rx != NULL && ret == 0) { |
| uint8_t read_crc = TMAG5170_GET_CRC(buffer_rx); |
| |
| TMAG5170_ZERO_CRC(buffer_rx); |
| crc = crc4_ti(TMAG5170_CRC_SEED, buffer_rx, TMAG5170_SPI_BUFFER_LEN); |
| if (read_crc != crc) { |
| return -EIO; |
| } |
| } |
| #endif |
| |
| return ret; |
| } |
| |
| static int tmag5170_write_register(const struct device *dev, uint32_t reg, uint16_t data) |
| { |
| uint8_t buffer_tx[4] = { reg, (data >> 8) & 0xFF, data & 0xFF, 0x00U }; |
| |
| return tmag5170_transmit(dev, buffer_tx, NULL); |
| } |
| |
| static int tmag5170_read_register(const struct device *dev, |
| uint32_t reg, |
| uint16_t *output, |
| uint8_t cmd) |
| { |
| uint8_t buffer_tx[4] = { BIT(7) | reg, 0x00U, 0x00U, (cmd & BIT_MASK(4U)) << 4U }; |
| uint8_t buffer_rx[4] = { 0x00U }; |
| |
| int ret = tmag5170_transmit(dev, buffer_tx, buffer_rx); |
| |
| *output = (buffer_rx[1] << 8) | buffer_rx[2]; |
| |
| return ret; |
| } |
| |
| static int tmag5170_convert_magn_reading_to_gauss(struct sensor_value *output, |
| uint16_t chan_reading, |
| uint8_t chan_range, |
| uint8_t chip_revision) |
| { |
| uint16_t max_range_mt = 0U; |
| |
| if (chan_range == TMAG5170_MAX_RANGE_50MT_IDX) { |
| max_range_mt = 50U; |
| } else if (chan_range == TMAG5170_MAX_RANGE_25MT_IDX) { |
| max_range_mt = 25U; |
| } else if (chan_range == TMAG5170_MAX_RANGE_100MT_IDX) { |
| max_range_mt = 100U; |
| } else { |
| return -ENOTSUP; |
| } |
| |
| if (chip_revision == TMAG5170_A2_REV) { |
| max_range_mt *= TMAG5170_MAX_RANGE_EXTEND_FACTOR; |
| } |
| |
| max_range_mt *= 2U; |
| |
| /* The sensor returns data in mT, we need to convert it to Gauss */ |
| uint32_t max_range_gauss = max_range_mt * TMAG5170_MT_TO_GAUSS_RATIO; |
| |
| /* Convert from 2's complementary system */ |
| int64_t result = chan_reading - ((chan_reading & 0x8000) << 1); |
| |
| result *= max_range_gauss; |
| |
| /* Scale to increase accuracy */ |
| result *= 100000; |
| |
| /* Divide as it is shown in datasheet */ |
| result /= 65536; |
| |
| /* Remove scale from the final result */ |
| output->val1 = result / 100000; |
| output->val2 = result % 100000; |
| |
| return 0; |
| } |
| |
| static void tmag5170_convert_temp_reading_to_celsius(struct sensor_value *output, |
| uint16_t chan_reading) |
| { |
| int32_t result = chan_reading - TMAG5170_T_ADC_T0; |
| |
| result = (TMAG5170_T_SENS_T0 * 100000) + (100000 * result / (int32_t)TMAG5170_T_ADC_RES); |
| |
| output->val1 = result / 100000; |
| output->val2 = (result % 100000) * 10; |
| } |
| |
| static void tmag5170_covert_angle_reading_to_degrees(struct sensor_value *output, |
| uint16_t chan_reading) |
| { |
| /* 12 MSBs store the integer part of the result, |
| * 4 LSBs store the fractional part of the result |
| */ |
| output->val1 = chan_reading >> 4; |
| output->val2 = ((chan_reading & 0xF) * 1000000) / 16; |
| } |
| |
| static int tmag5170_sample_fetch(const struct device *dev, |
| enum sensor_channel chan) |
| { |
| const struct tmag5170_dev_config *cfg = dev->config; |
| struct tmag5170_data *drv_data = dev->data; |
| int ret = 0; |
| |
| if (cfg->operating_mode == TMAG5170_STAND_BY_MODE || |
| cfg->operating_mode == TMAG5170_ACTIVE_TRIGGER_MODE) { |
| uint16_t read_status; |
| |
| tmag5170_read_register(dev, |
| TMAG5170_REG_SYS_STATUS, |
| &read_status, |
| TMAG5170_CMD_TRIGGER_CONVERSION); |
| |
| /* Wait for the measurement to be ready. |
| * The waiting time will vary depending on the configuration |
| */ |
| k_sleep(K_MSEC(5U)); |
| } |
| |
| switch (chan) { |
| case SENSOR_CHAN_MAGN_X: |
| ret = tmag5170_read_register(dev, TMAG5170_REG_X_CH_RESULT, &drv_data->x, 0U); |
| break; |
| case SENSOR_CHAN_MAGN_Y: |
| ret = tmag5170_read_register(dev, TMAG5170_REG_Y_CH_RESULT, &drv_data->y, 0U); |
| break; |
| case SENSOR_CHAN_MAGN_Z: |
| ret = tmag5170_read_register(dev, TMAG5170_REG_Z_CH_RESULT, &drv_data->z, 0U); |
| break; |
| case SENSOR_CHAN_MAGN_XYZ: |
| ret = tmag5170_read_register(dev, TMAG5170_REG_X_CH_RESULT, &drv_data->x, 0U); |
| |
| if (ret == 0) { |
| ret = tmag5170_read_register(dev, |
| TMAG5170_REG_Y_CH_RESULT, |
| &drv_data->y, |
| 0U); |
| } |
| if (ret == 0) { |
| ret = tmag5170_read_register(dev, |
| TMAG5170_REG_Z_CH_RESULT, |
| &drv_data->z, |
| 0U); |
| } |
| break; |
| case SENSOR_CHAN_ROTATION: |
| ret = tmag5170_read_register(dev, |
| TMAG5170_REG_ANGLE_RESULT, |
| &drv_data->angle, |
| 0U); |
| break; |
| case SENSOR_CHAN_AMBIENT_TEMP: |
| ret = tmag5170_read_register(dev, |
| TMAG5170_REG_TEMP_RESULT, |
| &drv_data->temperature, |
| 0U); |
| break; |
| case SENSOR_CHAN_ALL: |
| ret = tmag5170_read_register(dev, |
| TMAG5170_REG_TEMP_RESULT, |
| &drv_data->temperature, |
| 0U); |
| |
| if (ret == 0) { |
| ret = tmag5170_read_register(dev, |
| TMAG5170_REG_ANGLE_RESULT, |
| &drv_data->angle, |
| 0U); |
| } |
| |
| if (ret == 0) { |
| ret = tmag5170_read_register(dev, |
| TMAG5170_REG_X_CH_RESULT, |
| &drv_data->x, |
| 0U); |
| } |
| |
| if (ret == 0) { |
| ret = tmag5170_read_register(dev, |
| TMAG5170_REG_Y_CH_RESULT, |
| &drv_data->y, |
| 0U); |
| } |
| |
| if (ret == 0) { |
| ret = tmag5170_read_register(dev, |
| TMAG5170_REG_Z_CH_RESULT, |
| &drv_data->z, |
| 0U); |
| } |
| |
| break; |
| default: |
| ret = -ENOTSUP; |
| break; |
| } |
| |
| return ret; |
| } |
| |
| static int tmag5170_channel_get(const struct device *dev, |
| enum sensor_channel chan, |
| struct sensor_value *val) |
| { |
| const struct tmag5170_dev_config *cfg = dev->config; |
| struct tmag5170_data *drv_data = dev->data; |
| int ret = 0; |
| |
| switch (chan) { |
| case SENSOR_CHAN_MAGN_XYZ: |
| ret = tmag5170_convert_magn_reading_to_gauss(val, |
| drv_data->x, |
| cfg->x_range, |
| drv_data->chip_revision); |
| |
| if (ret == 0) { |
| ret = tmag5170_convert_magn_reading_to_gauss(val + 1, |
| drv_data->y, |
| cfg->y_range, |
| drv_data->chip_revision); |
| } |
| |
| if (ret == 0) { |
| ret = tmag5170_convert_magn_reading_to_gauss(val + 2, |
| drv_data->z, |
| cfg->z_range, |
| drv_data->chip_revision); |
| } |
| break; |
| case SENSOR_CHAN_MAGN_X: |
| ret = tmag5170_convert_magn_reading_to_gauss(val, |
| drv_data->x, |
| cfg->x_range, |
| drv_data->chip_revision); |
| break; |
| case SENSOR_CHAN_MAGN_Y: |
| ret = tmag5170_convert_magn_reading_to_gauss(val, |
| drv_data->y, |
| cfg->y_range, |
| drv_data->chip_revision); |
| break; |
| case SENSOR_CHAN_MAGN_Z: |
| ret = tmag5170_convert_magn_reading_to_gauss(val, |
| drv_data->z, |
| cfg->z_range, |
| drv_data->chip_revision); |
| break; |
| case SENSOR_CHAN_ROTATION: |
| tmag5170_covert_angle_reading_to_degrees(val, drv_data->angle); |
| break; |
| case SENSOR_CHAN_AMBIENT_TEMP: |
| tmag5170_convert_temp_reading_to_celsius(val, drv_data->temperature); |
| break; |
| default: |
| ret = -ENOTSUP; |
| break; |
| } |
| |
| return ret; |
| } |
| |
| static int tmag5170_init_registers(const struct device *dev) |
| { |
| const struct tmag5170_dev_config *cfg = dev->config; |
| struct tmag5170_data *drv_data = dev->data; |
| uint16_t test_cfg_reg = 0U; |
| int ret = 0; |
| |
| #if !defined(CONFIG_TMAG5170_CRC) |
| const uint8_t disable_crc_packet[4] = { 0x0FU, 0x0U, 0x04U, 0x07U }; |
| |
| ret = tmag5170_transmit_raw(cfg, disable_crc_packet, NULL); |
| #endif |
| if (ret == 0) { |
| ret = tmag5170_read_register(dev, TMAG5170_REG_TEST_CONFIG, &test_cfg_reg, 0U); |
| } |
| |
| if (ret == 0) { |
| drv_data->chip_revision = TMAG5170_VER_GET(test_cfg_reg); |
| |
| ret = tmag5170_write_register(dev, |
| TMAG5170_REG_SENSOR_CONFIG, |
| TMAG5170_ANGLE_EN_SET(cfg->angle_measurement) | |
| TMAG5170_SLEEPTIME_SET(cfg->sleep_time) | |
| TMAG5170_MAG_CH_EN_SET(cfg->magnetic_channels) | |
| TMAG5170_Z_RANGE_SET(cfg->z_range) | |
| TMAG5170_Y_RANGE_SET(cfg->y_range) | |
| TMAG5170_X_RANGE_SET(cfg->x_range)); |
| } |
| |
| #if defined(CONFIG_TMAG5170_TRIGGER) |
| if (ret == 0) { |
| ret = tmag5170_write_register(dev, |
| TMAG5170_REG_ALERT_CONFIG, |
| TMAG5170_RSLT_ALRT_SET(1U)); |
| } |
| #endif |
| if (ret == 0) { |
| ret = tmag5170_write_register(dev, |
| TMAG5170_REG_DEVICE_CONFIG, |
| TMAG5170_OPERATING_MODE_SET(cfg->operating_mode) | |
| TMAG5170_CONV_AVG_SET(cfg->oversampling) | |
| TMAG5170_MAG_TEMPCO_SET(cfg->magnet_type) | |
| TMAG5170_T_CH_EN_SET(cfg->tempeature_measurement) | |
| TMAG5170_T_RATE_SET(cfg->disable_temperature_oversampling)); |
| } |
| |
| return ret; |
| } |
| |
| #ifdef CONFIG_PM_DEVICE |
| static int tmag5170_pm_action(const struct device *dev, |
| enum pm_device_action action) |
| { |
| int ret_val = 0; |
| |
| switch (action) { |
| case PM_DEVICE_ACTION_RESUME: |
| tmag5170_write_register(dev, |
| TMAG5170_REG_DEVICE_CONFIG, |
| TMAG5170_OPERATING_MODE_SET(TMAG5170_CONFIGURATION_MODE)); |
| /* As per datasheet, waking up from deep-sleep can take up to 500us */ |
| k_sleep(K_USEC(500)); |
| ret_val = tmag5170_init_registers(dev); |
| break; |
| case PM_DEVICE_ACTION_SUSPEND: |
| ret_val = tmag5170_write_register(dev, |
| TMAG5170_REG_DEVICE_CONFIG, |
| TMAG5170_OPERATING_MODE_SET(TMAG5170_DEEP_SLEEP_MODE)); |
| break; |
| default: |
| ret_val = -ENOTSUP; |
| } |
| |
| return ret_val; |
| } |
| #endif /* CONFIG_PM_DEVICE */ |
| |
| static const struct sensor_driver_api tmag5170_driver_api = { |
| .sample_fetch = tmag5170_sample_fetch, |
| .channel_get = tmag5170_channel_get, |
| #if defined(CONFIG_TMAG5170_TRIGGER) |
| .trigger_set = tmag5170_trigger_set |
| #endif |
| }; |
| |
| static int tmag5170_init(const struct device *dev) |
| { |
| const struct tmag5170_dev_config *cfg = dev->config; |
| int ret = 0; |
| |
| if (!spi_is_ready_dt(&cfg->bus)) { |
| LOG_ERR("SPI dev %s not ready", cfg->bus.bus->name); |
| return -ENODEV; |
| } |
| |
| ret = tmag5170_init_registers(dev); |
| if (ret != 0) { |
| return ret; |
| } |
| |
| #if defined(CONFIG_TMAG5170_TRIGGER) |
| if (cfg->int_gpio.port) { |
| ret = tmag5170_trigger_init(dev); |
| } |
| #endif |
| |
| return ret; |
| } |
| |
| #define DEFINE_TMAG5170(_num) \ |
| static struct tmag5170_data tmag5170_data_##_num; \ |
| static const struct tmag5170_dev_config tmag5170_config_##_num = { \ |
| .bus = SPI_DT_SPEC_INST_GET(_num, \ |
| SPI_OP_MODE_MASTER | \ |
| SPI_TRANSFER_MSB | \ |
| SPI_WORD_SET(32), \ |
| 0), \ |
| .magnetic_channels = DT_INST_ENUM_IDX(_num, magnetic_channels), \ |
| .x_range = DT_INST_ENUM_IDX(_num, x_range), \ |
| .y_range = DT_INST_ENUM_IDX(_num, y_range), \ |
| .z_range = DT_INST_ENUM_IDX(_num, z_range), \ |
| .operating_mode = DT_INST_PROP(_num, operating_mode), \ |
| .oversampling = DT_INST_ENUM_IDX(_num, oversampling), \ |
| .tempeature_measurement = DT_INST_PROP(_num, enable_temperature_channel), \ |
| .magnet_type = DT_INST_ENUM_IDX(_num, magnet_type), \ |
| .angle_measurement = DT_INST_ENUM_IDX(_num, angle_measurement), \ |
| .disable_temperature_oversampling = DT_INST_PROP(_num, \ |
| disable_temperature_oversampling), \ |
| .sleep_time = DT_INST_ENUM_IDX(_num, sleep_time), \ |
| IF_ENABLED(CONFIG_TMAG5170_TRIGGER, \ |
| (.int_gpio = GPIO_DT_SPEC_INST_GET_OR(_num, int_gpios, { 0 }),)) \ |
| }; \ |
| PM_DEVICE_DT_INST_DEFINE(_num, tmag5170_pm_action); \ |
| \ |
| SENSOR_DEVICE_DT_INST_DEFINE(_num, \ |
| tmag5170_init, \ |
| PM_DEVICE_DT_INST_GET(_num), \ |
| &tmag5170_data_##_num, \ |
| &tmag5170_config_##_num, \ |
| POST_KERNEL, \ |
| CONFIG_SENSOR_INIT_PRIORITY, \ |
| &tmag5170_driver_api); |
| |
| DT_INST_FOREACH_STATUS_OKAY(DEFINE_TMAG5170) |