/* adxl362.c - ADXL362 Three-Axis Digital Accelerometers */

/*
 * Copyright (c) 2017 IpTronix S.r.l.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT adi_adxl362

#include <zephyr/kernel.h>
#include <zephyr/devicetree.h>
#include <string.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/init.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/__assert.h>
#include <zephyr/drivers/spi.h>
#include <zephyr/logging/log.h>

#include "adxl362.h"

LOG_MODULE_REGISTER(ADXL362, CONFIG_SENSOR_LOG_LEVEL);

static int adxl362_reg_access(const struct device *dev, uint8_t cmd,
			      uint8_t reg_addr, void *data, size_t length)
{
	const struct adxl362_config *cfg = dev->config;
	uint8_t access[2] = { cmd, reg_addr };
	const struct spi_buf buf[2] = {
		{
			.buf = access,
			.len = 2
		},
		{
			.buf = data,
			.len = length
		}
	};
	struct spi_buf_set tx = {
		.buffers = buf,
	};

	if (cmd == ADXL362_READ_REG) {
		const struct spi_buf_set rx = {
			.buffers = buf,
			.count = 2
		};

		tx.count = 1;

		return spi_transceive_dt(&cfg->bus, &tx, &rx);
	}

	tx.count = 2;

	return spi_write_dt(&cfg->bus, &tx);
}

static inline int adxl362_set_reg(const struct device *dev,
				  uint16_t register_value,
				  uint8_t register_address, uint8_t count)
{
	return adxl362_reg_access(dev, ADXL362_WRITE_REG,
				  register_address, &register_value, count);
}

int adxl362_reg_write_mask(const struct device *dev, uint8_t register_address,
			   uint8_t mask, uint8_t data)
{
	int ret;
	uint8_t tmp;

	ret = adxl362_reg_access(dev, ADXL362_READ_REG,
				 register_address, &tmp, 1);

	if (ret) {
		return ret;
	}

	tmp &= ~mask;
	tmp |= data;

	return adxl362_reg_access(dev, ADXL362_WRITE_REG,
				  register_address, &tmp, 1);
}

static inline int adxl362_get_reg(const struct device *dev, uint8_t *read_buf,
				  uint8_t register_address, uint8_t count)
{

	return adxl362_reg_access(dev, ADXL362_READ_REG,
				  register_address, read_buf, count);
}

#if defined(CONFIG_ADXL362_TRIGGER)
static int adxl362_interrupt_config(const struct device *dev,
				    uint8_t int1,
				    uint8_t int2)
{
	int ret;

	ret = adxl362_reg_access(dev, ADXL362_WRITE_REG,
				 ADXL362_REG_INTMAP1, &int1, 1);

	if (ret) {
		return ret;
	}

	return ret = adxl362_reg_access(dev, ADXL362_WRITE_REG,
					ADXL362_REG_INTMAP2, &int2, 1);
}

int adxl362_get_status(const struct device *dev, uint8_t *status)
{
	return adxl362_get_reg(dev, status, ADXL362_REG_STATUS, 1);
}

int adxl362_clear_data_ready(const struct device *dev)
{
	uint8_t buf;
	/* Reading any data register clears the data ready interrupt */
	return adxl362_get_reg(dev, &buf, ADXL362_REG_XDATA, 1);
}
#endif

static int adxl362_software_reset(const struct device *dev)
{
	return adxl362_set_reg(dev, ADXL362_RESET_KEY,
			       ADXL362_REG_SOFT_RESET, 1);
}

#if defined(CONFIG_ADXL362_ACCEL_ODR_RUNTIME)
/*
 * Output data rate map with allowed frequencies:
 * freq = freq_int + freq_milli / 1000
 *
 * Since we don't need a finer frequency resolution than milliHz, use uint16_t
 * to save some flash.
 */
static const struct {
	uint16_t freq_int;
	uint16_t freq_milli; /* User should convert to uHz before setting the
			      * SENSOR_ATTR_SAMPLING_FREQUENCY attribute.
			      */
} adxl362_odr_map[] = {
	{ 12, 500 },
	{ 25, 0 },
	{ 50, 0 },
	{ 100, 0 },
	{ 200, 0 },
	{ 400, 0 },
};

static int adxl362_freq_to_odr_val(uint16_t freq_int, uint16_t freq_milli)
{
	size_t i;

	/* An ODR of 0 Hz is not allowed */
	if (freq_int == 0U && freq_milli == 0U) {
		return -EINVAL;
	}

	for (i = 0; i < ARRAY_SIZE(adxl362_odr_map); i++) {
		if (freq_int < adxl362_odr_map[i].freq_int ||
		    (freq_int == adxl362_odr_map[i].freq_int &&
		     freq_milli <= adxl362_odr_map[i].freq_milli)) {
			return i;
		}
	}

	return -EINVAL;
}
#endif /* CONFIG_ADXL362_ACCEL_ODR_RUNTIME */

#if defined(CONFIG_ADXL362_ACCEL_RANGE_RUNTIME)
static const struct adxl362_range {
	uint16_t range;
	uint8_t reg_val;
} adxl362_acc_range_map[] = {
	{2,	ADXL362_RANGE_2G},
	{4,	ADXL362_RANGE_4G},
	{8,	ADXL362_RANGE_8G},
};

static int32_t adxl362_range_to_reg_val(uint16_t range)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(adxl362_acc_range_map); i++) {
		if (range <= adxl362_acc_range_map[i].range) {
			return adxl362_acc_range_map[i].reg_val;
		}
	}

	return -EINVAL;
}
#endif /* CONFIG_ADXL362_ACCEL_RANGE_RUNTIME */

static int adxl362_set_range(const struct device *dev, uint8_t range)
{
	struct adxl362_data *adxl362_data = dev->data;
	uint8_t old_filter_ctl;
	uint8_t new_filter_ctl;
	int ret;

	ret = adxl362_get_reg(dev, &old_filter_ctl, ADXL362_REG_FILTER_CTL, 1);
	if (ret) {
		return ret;
	}

	new_filter_ctl = old_filter_ctl & ~ADXL362_FILTER_CTL_RANGE(0x3);
	new_filter_ctl = new_filter_ctl | ADXL362_FILTER_CTL_RANGE(range);
	ret = adxl362_set_reg(dev, new_filter_ctl, ADXL362_REG_FILTER_CTL, 1);
	if (ret) {
		return ret;
	}

	adxl362_data->selected_range = range;
	return 0;
}

static int adxl362_set_output_rate(const struct device *dev, uint8_t out_rate)
{
	uint8_t old_filter_ctl;
	uint8_t new_filter_ctl;

	adxl362_get_reg(dev, &old_filter_ctl, ADXL362_REG_FILTER_CTL, 1);
	new_filter_ctl = old_filter_ctl & ~ADXL362_FILTER_CTL_ODR(0x7);
	new_filter_ctl = new_filter_ctl | ADXL362_FILTER_CTL_ODR(out_rate);
	adxl362_set_reg(dev, new_filter_ctl, ADXL362_REG_FILTER_CTL, 1);

	return 0;
}


static int axl362_acc_config(const struct device *dev,
			     enum sensor_channel chan,
			     enum sensor_attribute attr,
			     const struct sensor_value *val)
{
	switch (attr) {
#if defined(CONFIG_ADXL362_ACCEL_RANGE_RUNTIME)
	case SENSOR_ATTR_FULL_SCALE:
	{
		int range_reg;

		range_reg = adxl362_range_to_reg_val(sensor_ms2_to_g(val));
		if (range_reg < 0) {
			LOG_DBG("invalid range requested.");
			return -ENOTSUP;
		}

		return adxl362_set_range(dev, range_reg);
	}
	break;
#endif
#if defined(CONFIG_ADXL362_ACCEL_ODR_RUNTIME)
	case SENSOR_ATTR_SAMPLING_FREQUENCY:
	{
		int out_rate;

		out_rate = adxl362_freq_to_odr_val(val->val1,
						   val->val2 / 1000);
		if (out_rate < 0) {
			LOG_DBG("invalid output rate.");
			return -ENOTSUP;
		}

		return adxl362_set_output_rate(dev, out_rate);
	}
	break;
#endif
	default:
		LOG_DBG("Accel attribute not supported.");
		return -ENOTSUP;
	}

	return 0;
}

static int adxl362_attr_set_thresh(const struct device *dev,
				   enum sensor_channel chan,
				   enum sensor_attribute attr,
				   const struct sensor_value *val)
{
	uint8_t reg;
	uint16_t threshold = val->val1;
	size_t ret;

	if (chan != SENSOR_CHAN_ACCEL_X &&
	    chan != SENSOR_CHAN_ACCEL_Y &&
	    chan != SENSOR_CHAN_ACCEL_Z) {
		return -EINVAL;
	}

	if (threshold > 2047) {
		return -EINVAL;
	}

	/* Configure motion threshold. */
	if (attr == SENSOR_ATTR_UPPER_THRESH) {
		reg = ADXL362_REG_THRESH_ACT_L;
	} else {
		reg = ADXL362_REG_THRESH_INACT_L;
	}

	ret = adxl362_set_reg(dev, (threshold & 0x7FF), reg, 2);

	return ret;
}

static int adxl362_attr_set(const struct device *dev,
			    enum sensor_channel chan,
			    enum sensor_attribute attr,
			    const struct sensor_value *val)
{
	switch (attr) {
	case SENSOR_ATTR_UPPER_THRESH:
	case SENSOR_ATTR_LOWER_THRESH:
		return adxl362_attr_set_thresh(dev, chan, attr, val);
	case SENSOR_ATTR_HYSTERESIS:
	{
		uint16_t timeout = val->val1;

		return adxl362_set_reg(dev, timeout, ADXL362_REG_TIME_INACT_L, 2);
	}
	default:
		/* Do nothing */
		break;
	}

	switch (chan) {
	case SENSOR_CHAN_ACCEL_X:
	case SENSOR_CHAN_ACCEL_Y:
	case SENSOR_CHAN_ACCEL_Z:
	case SENSOR_CHAN_ACCEL_XYZ:
		return axl362_acc_config(dev, chan, attr, val);
	default:
		LOG_DBG("attr_set() not supported on this channel.");
		return -ENOTSUP;
	}

	return 0;
}

static int adxl362_fifo_setup(const struct device *dev, uint8_t mode,
			      uint16_t water_mark_lvl, uint8_t en_temp_read)
{
	uint8_t write_val;
	int ret;

	write_val = ADXL362_FIFO_CTL_FIFO_MODE(mode) |
		   (en_temp_read * ADXL362_FIFO_CTL_FIFO_TEMP) |
		   ADXL362_FIFO_CTL_AH;
	ret = adxl362_set_reg(dev, write_val, ADXL362_REG_FIFO_CTL, 1);
	if (ret) {
		return ret;
	}

	ret = adxl362_set_reg(dev, water_mark_lvl, ADXL362_REG_FIFO_SAMPLES, 1);
	if (ret) {
		return ret;
	}

	return 0;
}

static int adxl362_setup_activity_detection(const struct device *dev,
					    uint8_t ref_or_abs,
					    uint16_t threshold,
					    uint8_t time)
{
	uint8_t old_act_inact_reg;
	uint8_t new_act_inact_reg;
	int ret;

	/**
	 * mode
	 *              must be one of the following:
	 *			ADXL362_FIFO_DISABLE      -  FIFO is disabled.
	 *			ADXL362_FIFO_OLDEST_SAVED -  Oldest saved mode.
	 *			ADXL362_FIFO_STREAM       -  Stream mode.
	 *			ADXL362_FIFO_TRIGGERED    -  Triggered mode.
	 * water_mark_lvl
	 *              Specifies the number of samples to store in the FIFO.
	 * en_temp_read
	 *              Store Temperature Data to FIFO.
	 *              1 - temperature data is stored in the FIFO
	 *                  together with x-, y- and x-axis data.
	 *          0 - temperature data is skipped.
	 */

	/* Configure motion threshold and activity timer. */
	ret = adxl362_set_reg(dev, (threshold & 0x7FF),
			      ADXL362_REG_THRESH_ACT_L, 2);
	if (ret) {
		return ret;
	}

	ret = adxl362_set_reg(dev, time, ADXL362_REG_TIME_ACT, 1);
	if (ret) {
		return ret;
	}

	/* Enable activity interrupt and select a referenced or absolute
	 * configuration.
	 */
	ret = adxl362_get_reg(dev, &old_act_inact_reg,
			      ADXL362_REG_ACT_INACT_CTL, 1);
	if (ret) {
		return ret;
	}

	new_act_inact_reg = old_act_inact_reg & ~ADXL362_ACT_INACT_CTL_ACT_REF;
	new_act_inact_reg |= ADXL362_ACT_INACT_CTL_ACT_EN |
			  (ref_or_abs * ADXL362_ACT_INACT_CTL_ACT_REF);
	ret = adxl362_set_reg(dev, new_act_inact_reg,
			      ADXL362_REG_ACT_INACT_CTL, 1);
	if (ret) {
		return ret;
	}

	return 0;
}

static int adxl362_setup_inactivity_detection(const struct device *dev,
					      uint8_t ref_or_abs,
					      uint16_t threshold,
					      uint16_t time)
{
	uint8_t old_act_inact_reg;
	uint8_t new_act_inact_reg;
	int ret;

	/* Configure motion threshold and inactivity timer. */
	ret = adxl362_set_reg(dev, (threshold & 0x7FF),
			      ADXL362_REG_THRESH_INACT_L, 2);
	if (ret) {
		return ret;
	}

	ret = adxl362_set_reg(dev, time, ADXL362_REG_TIME_INACT_L, 2);
	if (ret) {
		return ret;
	}

	/* Enable inactivity interrupt and select a referenced or
	 * absolute configuration.
	 */
	ret = adxl362_get_reg(dev, &old_act_inact_reg,
			      ADXL362_REG_ACT_INACT_CTL, 1);
	if (ret) {
		return ret;
	}

	new_act_inact_reg = old_act_inact_reg &
			    ~ADXL362_ACT_INACT_CTL_INACT_REF;
	new_act_inact_reg |= ADXL362_ACT_INACT_CTL_INACT_EN |
			     (ref_or_abs * ADXL362_ACT_INACT_CTL_INACT_REF);
	ret = adxl362_set_reg(dev, new_act_inact_reg,
			      ADXL362_REG_ACT_INACT_CTL, 1);
	if (ret) {
		return ret;
	}

	return 0;
}

int adxl362_set_interrupt_mode(const struct device *dev, uint8_t mode)
{
	uint8_t old_act_inact_reg;
	uint8_t new_act_inact_reg;
	int ret;

	LOG_DBG("Mode: %d", mode);

	if (mode != ADXL362_MODE_DEFAULT &&
	    mode != ADXL362_MODE_LINK &&
	    mode != ADXL362_MODE_LOOP) {
		    LOG_ERR("Wrong mode");
		    return -EINVAL;
	}

	/* Select desired interrupt mode. */
	ret = adxl362_get_reg(dev, &old_act_inact_reg,
			      ADXL362_REG_ACT_INACT_CTL, 1);
	if (ret) {
		return ret;
	}

	new_act_inact_reg = old_act_inact_reg &
			    ~ADXL362_ACT_INACT_CTL_LINKLOOP(3);
	new_act_inact_reg |= old_act_inact_reg |
			    ADXL362_ACT_INACT_CTL_LINKLOOP(mode);

	ret = adxl362_set_reg(dev, new_act_inact_reg,
			      ADXL362_REG_ACT_INACT_CTL, 1);

	if (ret) {
		return ret;
	}

	return 0;
}

static int adxl362_sample_fetch(const struct device *dev,
				enum sensor_channel chan)
{
	struct adxl362_data *data = dev->data;
	int16_t buf[4];
	int ret;

	__ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL);

	ret = adxl362_get_reg(dev, (uint8_t *)buf, ADXL362_REG_XDATA_L,
			      sizeof(buf));
	if (ret) {
		return ret;
	}

	data->acc_x = sys_le16_to_cpu(buf[0]);
	data->acc_y = sys_le16_to_cpu(buf[1]);
	data->acc_z = sys_le16_to_cpu(buf[2]);
	data->temp = sys_le16_to_cpu(buf[3]);

	return 0;
}

static inline int adxl362_range_to_scale(int range)
{
	/* See table 1 in specifications section of datasheet */
	switch (range) {
	case ADXL362_RANGE_2G:
		return ADXL362_ACCEL_2G_LSB_PER_G;
	case ADXL362_RANGE_4G:
		return ADXL362_ACCEL_4G_LSB_PER_G;
	case ADXL362_RANGE_8G:
		return ADXL362_ACCEL_8G_LSB_PER_G;
	default:
		return -EINVAL;
	}
}

static void adxl362_accel_convert(struct sensor_value *val, int accel,
				  int range)
{
	int scale = adxl362_range_to_scale(range);
	long micro_ms2 = accel * SENSOR_G / scale;

	__ASSERT_NO_MSG(scale != -EINVAL);

	val->val1 = micro_ms2 / 1000000;
	val->val2 = micro_ms2 % 1000000;
}

static void adxl362_temp_convert(struct sensor_value *val, int temp)
{
	/* See sensitivity and bias specifications in table 1 of datasheet */
	int milli_c = (temp - ADXL362_TEMP_BIAS_LSB) * ADXL362_TEMP_MC_PER_LSB;

	val->val1 = milli_c / 1000;
	val->val2 = (milli_c % 1000) * 1000;
}

static int adxl362_channel_get(const struct device *dev,
			       enum sensor_channel chan,
			       struct sensor_value *val)
{
	struct adxl362_data *data = dev->data;

	switch (chan) {
	case SENSOR_CHAN_ACCEL_X: /* Acceleration on the X axis, in m/s^2. */
		adxl362_accel_convert(val, data->acc_x, data->selected_range);
		break;
	case SENSOR_CHAN_ACCEL_Y: /* Acceleration on the Y axis, in m/s^2. */
		adxl362_accel_convert(val, data->acc_y, data->selected_range);
		break;
	case SENSOR_CHAN_ACCEL_Z: /* Acceleration on the Z axis, in m/s^2. */
		adxl362_accel_convert(val, data->acc_z,  data->selected_range);
		break;
	case SENSOR_CHAN_ACCEL_XYZ: /* Acceleration on the XYZ axis, in m/s^2. */
		for (size_t i = 0; i < 3; i++) {
			adxl362_accel_convert(&val[i], data->acc_xyz[i], data->selected_range);
		}
		break;
	case SENSOR_CHAN_DIE_TEMP: /* Temperature in degrees Celsius. */
		adxl362_temp_convert(val, data->temp);
		break;
	default:
		return -ENOTSUP;
	}

	return 0;
}

static const struct sensor_driver_api adxl362_api_funcs = {
	.attr_set     = adxl362_attr_set,
	.sample_fetch = adxl362_sample_fetch,
	.channel_get  = adxl362_channel_get,
#ifdef CONFIG_ADXL362_TRIGGER
	.trigger_set = adxl362_trigger_set,
#endif
};

static int adxl362_chip_init(const struct device *dev)
{
	const struct adxl362_config *config = dev->config;
	int ret;

	/* Configures activity detection.
	 *	Referenced/Absolute Activity or Inactivity Select.
	 *		0 - absolute mode.
	 *		1 - referenced mode.
	 *	threshold
	 *		11-bit unsigned value that the adxl362 samples are
	 *		compared to.
	 *	time
	 *		8-bit value written to the activity timer register.
	 *		The amount of time (in seconds) is:
	 *			time / ODR,
	 *		where ODR - is the output data rate.
	 */
	ret =
	adxl362_setup_activity_detection(dev,
					 CONFIG_ADXL362_ABS_REF_MODE,
					 CONFIG_ADXL362_ACTIVITY_THRESHOLD,
					 CONFIG_ADXL362_ACTIVITY_TIME);
	if (ret) {
		return ret;
	}

	/* Configures inactivity detection.
	 *	Referenced/Absolute Activity or Inactivity Select.
	 *		0 - absolute mode.
	 *		1 - referenced mode.
	 *	threshold
	 *		11-bit unsigned value that the adxl362 samples are
	 *		compared to.
	 *	time
	 *		16-bit value written to the activity timer register.
	 *		The amount of time (in seconds) is:
	 *			time / ODR,
	 *		where ODR - is the output data rate.
	 */
	ret =
	adxl362_setup_inactivity_detection(dev,
					   CONFIG_ADXL362_ABS_REF_MODE,
					   CONFIG_ADXL362_INACTIVITY_THRESHOLD,
					   CONFIG_ADXL362_INACTIVITY_TIME);
	if (ret) {
		return ret;
	}

	/* Configures the FIFO feature. */
	ret = adxl362_fifo_setup(dev, ADXL362_FIFO_DISABLE, 0, 0);
	if (ret) {
		return ret;
	}

	/* Selects the measurement range.
	 * options are:
	 *		ADXL362_RANGE_2G  -  +-2 g
	 *		ADXL362_RANGE_4G  -  +-4 g
	 *		ADXL362_RANGE_8G  -  +-8 g
	 */
	ret = adxl362_set_range(dev, ADXL362_DEFAULT_RANGE_ACC);
	if (ret) {
		return ret;
	}

	/* Selects the Output Data Rate of the device.
	 * Options are:
	 *		ADXL362_ODR_12_5_HZ  -  12.5Hz
	 *		ADXL362_ODR_25_HZ    -  25Hz
	 *		ADXL362_ODR_50_HZ    -  50Hz
	 *		ADXL362_ODR_100_HZ   -  100Hz
	 *		ADXL362_ODR_200_HZ   -  200Hz
	 *		ADXL362_ODR_400_HZ   -  400Hz
	 */
	ret = adxl362_set_output_rate(dev, ADXL362_DEFAULT_ODR_ACC);
	if (ret) {
		return ret;
	}

	/* Places the device into measure mode, enable wakeup mode and autosleep if desired. */
	LOG_DBG("setting pwrctl: 0x%02x", config->power_ctl);
	ret = adxl362_set_reg(dev, config->power_ctl, ADXL362_REG_POWER_CTL, 1);
	if (ret) {
		return ret;
	}

	return 0;
}

/**
 * @brief Initializes communication with the device and checks if the part is
 *        present by reading the device id.
 *
 * @return  0 - the initialization was successful and the device is present;
 *         -1 - an error occurred.
 *
 */
static int adxl362_init(const struct device *dev)
{
	const struct adxl362_config *config = dev->config;
	uint8_t value;
	int err;

	if (!spi_is_ready_dt(&config->bus)) {
		LOG_DBG("spi device not ready: %s", config->bus.bus->name);
		return -EINVAL;
	}

	err = adxl362_software_reset(dev);

	if (err) {
		LOG_ERR("adxl362_software_reset failed, error %d\n", err);
		return -ENODEV;
	}

	k_sleep(K_MSEC(5));

	adxl362_get_reg(dev, &value, ADXL362_REG_PARTID, 1);
	if (value != ADXL362_PART_ID) {
		LOG_ERR("wrong part_id: %d\n", value);
		return -ENODEV;
	}

	if (adxl362_chip_init(dev) < 0) {
		return -ENODEV;
	}

#if defined(CONFIG_ADXL362_TRIGGER)
	if (config->interrupt.port) {
		if (adxl362_init_interrupt(dev) < 0) {
			LOG_ERR("Failed to initialize interrupt!");
			return -EIO;
		}

		if (adxl362_interrupt_config(dev,
					config->int1_config,
					config->int2_config) < 0) {
			LOG_ERR("Failed to configure interrupt");
			return -EIO;
		}
	}
#endif

	return 0;
}

#define ADXL362_DEFINE(inst)									\
	static struct adxl362_data adxl362_data_##inst;						\
												\
	static const struct adxl362_config adxl362_config_##inst = {				\
		.bus = SPI_DT_SPEC_INST_GET(inst, SPI_WORD_SET(8) | SPI_TRANSFER_MSB, 0),	\
		.power_ctl = ADXL362_POWER_CTL_MEASURE(ADXL362_MEASURE_ON) |			\
			(DT_INST_PROP(inst, wakeup_mode) * ADXL362_POWER_CTL_WAKEUP) |		\
			(DT_INST_PROP(inst, autosleep) * ADXL362_POWER_CTL_AUTOSLEEP),		\
		IF_ENABLED(CONFIG_ADXL362_TRIGGER,						\
			   (.interrupt = GPIO_DT_SPEC_INST_GET_OR(inst, int1_gpios, { 0 }),))	\
	};											\
												\
	SENSOR_DEVICE_DT_INST_DEFINE(inst, adxl362_init, NULL, &adxl362_data_##inst,		\
			&adxl362_config_##inst, POST_KERNEL,					\
			CONFIG_SENSOR_INIT_PRIORITY, &adxl362_api_funcs);			\

DT_INST_FOREACH_STATUS_OKAY(ADXL362_DEFINE)
