162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * ADIS16475 IMU driver
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright 2019 Analog Devices Inc.
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci#include <linux/bitfield.h>
862306a36Sopenharmony_ci#include <linux/bitops.h>
962306a36Sopenharmony_ci#include <linux/clk.h>
1062306a36Sopenharmony_ci#include <linux/debugfs.h>
1162306a36Sopenharmony_ci#include <linux/delay.h>
1262306a36Sopenharmony_ci#include <linux/device.h>
1362306a36Sopenharmony_ci#include <linux/kernel.h>
1462306a36Sopenharmony_ci#include <linux/iio/buffer.h>
1562306a36Sopenharmony_ci#include <linux/iio/iio.h>
1662306a36Sopenharmony_ci#include <linux/iio/imu/adis.h>
1762306a36Sopenharmony_ci#include <linux/iio/trigger_consumer.h>
1862306a36Sopenharmony_ci#include <linux/irq.h>
1962306a36Sopenharmony_ci#include <linux/lcm.h>
2062306a36Sopenharmony_ci#include <linux/math.h>
2162306a36Sopenharmony_ci#include <linux/module.h>
2262306a36Sopenharmony_ci#include <linux/mod_devicetable.h>
2362306a36Sopenharmony_ci#include <linux/property.h>
2462306a36Sopenharmony_ci#include <linux/spi/spi.h>
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci#define ADIS16475_REG_DIAG_STAT		0x02
2762306a36Sopenharmony_ci#define ADIS16475_REG_X_GYRO_L		0x04
2862306a36Sopenharmony_ci#define ADIS16475_REG_Y_GYRO_L		0x08
2962306a36Sopenharmony_ci#define ADIS16475_REG_Z_GYRO_L		0x0C
3062306a36Sopenharmony_ci#define ADIS16475_REG_X_ACCEL_L		0x10
3162306a36Sopenharmony_ci#define ADIS16475_REG_Y_ACCEL_L		0x14
3262306a36Sopenharmony_ci#define ADIS16475_REG_Z_ACCEL_L		0x18
3362306a36Sopenharmony_ci#define ADIS16475_REG_TEMP_OUT		0x1c
3462306a36Sopenharmony_ci#define ADIS16475_REG_X_GYRO_BIAS_L	0x40
3562306a36Sopenharmony_ci#define ADIS16475_REG_Y_GYRO_BIAS_L	0x44
3662306a36Sopenharmony_ci#define ADIS16475_REG_Z_GYRO_BIAS_L	0x48
3762306a36Sopenharmony_ci#define ADIS16475_REG_X_ACCEL_BIAS_L	0x4c
3862306a36Sopenharmony_ci#define ADIS16475_REG_Y_ACCEL_BIAS_L	0x50
3962306a36Sopenharmony_ci#define ADIS16475_REG_Z_ACCEL_BIAS_L	0x54
4062306a36Sopenharmony_ci#define ADIS16475_REG_FILT_CTRL		0x5c
4162306a36Sopenharmony_ci#define ADIS16475_FILT_CTRL_MASK	GENMASK(2, 0)
4262306a36Sopenharmony_ci#define ADIS16475_FILT_CTRL(x)		FIELD_PREP(ADIS16475_FILT_CTRL_MASK, x)
4362306a36Sopenharmony_ci#define ADIS16475_REG_MSG_CTRL		0x60
4462306a36Sopenharmony_ci#define ADIS16475_MSG_CTRL_DR_POL_MASK	BIT(0)
4562306a36Sopenharmony_ci#define ADIS16475_MSG_CTRL_DR_POL(x) \
4662306a36Sopenharmony_ci				FIELD_PREP(ADIS16475_MSG_CTRL_DR_POL_MASK, x)
4762306a36Sopenharmony_ci#define ADIS16475_SYNC_MODE_MASK	GENMASK(4, 2)
4862306a36Sopenharmony_ci#define ADIS16475_SYNC_MODE(x)		FIELD_PREP(ADIS16475_SYNC_MODE_MASK, x)
4962306a36Sopenharmony_ci#define ADIS16475_REG_UP_SCALE		0x62
5062306a36Sopenharmony_ci#define ADIS16475_REG_DEC_RATE		0x64
5162306a36Sopenharmony_ci#define ADIS16475_REG_GLOB_CMD		0x68
5262306a36Sopenharmony_ci#define ADIS16475_REG_FIRM_REV		0x6c
5362306a36Sopenharmony_ci#define ADIS16475_REG_FIRM_DM		0x6e
5462306a36Sopenharmony_ci#define ADIS16475_REG_FIRM_Y		0x70
5562306a36Sopenharmony_ci#define ADIS16475_REG_PROD_ID		0x72
5662306a36Sopenharmony_ci#define ADIS16475_REG_SERIAL_NUM	0x74
5762306a36Sopenharmony_ci#define ADIS16475_REG_FLASH_CNT		0x7c
5862306a36Sopenharmony_ci#define ADIS16500_BURST32_MASK		BIT(9)
5962306a36Sopenharmony_ci#define ADIS16500_BURST32(x)		FIELD_PREP(ADIS16500_BURST32_MASK, x)
6062306a36Sopenharmony_ci/* number of data elements in burst mode */
6162306a36Sopenharmony_ci#define ADIS16475_BURST32_MAX_DATA	32
6262306a36Sopenharmony_ci#define ADIS16475_BURST_MAX_DATA	20
6362306a36Sopenharmony_ci#define ADIS16475_MAX_SCAN_DATA		20
6462306a36Sopenharmony_ci/* spi max speed in brust mode */
6562306a36Sopenharmony_ci#define ADIS16475_BURST_MAX_SPEED	1000000
6662306a36Sopenharmony_ci#define ADIS16475_LSB_DEC_MASK		0
6762306a36Sopenharmony_ci#define ADIS16475_LSB_FIR_MASK		1
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_cienum {
7062306a36Sopenharmony_ci	ADIS16475_SYNC_DIRECT = 1,
7162306a36Sopenharmony_ci	ADIS16475_SYNC_SCALED,
7262306a36Sopenharmony_ci	ADIS16475_SYNC_OUTPUT,
7362306a36Sopenharmony_ci	ADIS16475_SYNC_PULSE = 5,
7462306a36Sopenharmony_ci};
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_cistruct adis16475_sync {
7762306a36Sopenharmony_ci	u16 sync_mode;
7862306a36Sopenharmony_ci	u16 min_rate;
7962306a36Sopenharmony_ci	u16 max_rate;
8062306a36Sopenharmony_ci};
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_cistruct adis16475_chip_info {
8362306a36Sopenharmony_ci	const struct iio_chan_spec *channels;
8462306a36Sopenharmony_ci	const struct adis16475_sync *sync;
8562306a36Sopenharmony_ci	const struct adis_data adis_data;
8662306a36Sopenharmony_ci	const char *name;
8762306a36Sopenharmony_ci	u32 num_channels;
8862306a36Sopenharmony_ci	u32 gyro_max_val;
8962306a36Sopenharmony_ci	u32 gyro_max_scale;
9062306a36Sopenharmony_ci	u32 accel_max_val;
9162306a36Sopenharmony_ci	u32 accel_max_scale;
9262306a36Sopenharmony_ci	u32 temp_scale;
9362306a36Sopenharmony_ci	u32 int_clk;
9462306a36Sopenharmony_ci	u16 max_dec;
9562306a36Sopenharmony_ci	u8 num_sync;
9662306a36Sopenharmony_ci	bool has_burst32;
9762306a36Sopenharmony_ci};
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_cistruct adis16475 {
10062306a36Sopenharmony_ci	const struct adis16475_chip_info *info;
10162306a36Sopenharmony_ci	struct adis adis;
10262306a36Sopenharmony_ci	u32 clk_freq;
10362306a36Sopenharmony_ci	bool burst32;
10462306a36Sopenharmony_ci	unsigned long lsb_flag;
10562306a36Sopenharmony_ci	u16 sync_mode;
10662306a36Sopenharmony_ci	/* Alignment needed for the timestamp */
10762306a36Sopenharmony_ci	__be16 data[ADIS16475_MAX_SCAN_DATA] __aligned(8);
10862306a36Sopenharmony_ci};
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_cienum {
11162306a36Sopenharmony_ci	ADIS16475_SCAN_GYRO_X,
11262306a36Sopenharmony_ci	ADIS16475_SCAN_GYRO_Y,
11362306a36Sopenharmony_ci	ADIS16475_SCAN_GYRO_Z,
11462306a36Sopenharmony_ci	ADIS16475_SCAN_ACCEL_X,
11562306a36Sopenharmony_ci	ADIS16475_SCAN_ACCEL_Y,
11662306a36Sopenharmony_ci	ADIS16475_SCAN_ACCEL_Z,
11762306a36Sopenharmony_ci	ADIS16475_SCAN_TEMP,
11862306a36Sopenharmony_ci};
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_cistatic bool low_rate_allow;
12162306a36Sopenharmony_cimodule_param(low_rate_allow, bool, 0444);
12262306a36Sopenharmony_ciMODULE_PARM_DESC(low_rate_allow,
12362306a36Sopenharmony_ci		 "Allow IMU rates below the minimum advisable when external clk is used in SCALED mode (default: N)");
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci#ifdef CONFIG_DEBUG_FS
12662306a36Sopenharmony_cistatic ssize_t adis16475_show_firmware_revision(struct file *file,
12762306a36Sopenharmony_ci						char __user *userbuf,
12862306a36Sopenharmony_ci						size_t count, loff_t *ppos)
12962306a36Sopenharmony_ci{
13062306a36Sopenharmony_ci	struct adis16475 *st = file->private_data;
13162306a36Sopenharmony_ci	char buf[7];
13262306a36Sopenharmony_ci	size_t len;
13362306a36Sopenharmony_ci	u16 rev;
13462306a36Sopenharmony_ci	int ret;
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci	ret = adis_read_reg_16(&st->adis, ADIS16475_REG_FIRM_REV, &rev);
13762306a36Sopenharmony_ci	if (ret)
13862306a36Sopenharmony_ci		return ret;
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci	len = scnprintf(buf, sizeof(buf), "%x.%x\n", rev >> 8, rev & 0xff);
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci	return simple_read_from_buffer(userbuf, count, ppos, buf, len);
14362306a36Sopenharmony_ci}
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_cistatic const struct file_operations adis16475_firmware_revision_fops = {
14662306a36Sopenharmony_ci	.open = simple_open,
14762306a36Sopenharmony_ci	.read = adis16475_show_firmware_revision,
14862306a36Sopenharmony_ci	.llseek = default_llseek,
14962306a36Sopenharmony_ci	.owner = THIS_MODULE,
15062306a36Sopenharmony_ci};
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_cistatic ssize_t adis16475_show_firmware_date(struct file *file,
15362306a36Sopenharmony_ci					    char __user *userbuf,
15462306a36Sopenharmony_ci					    size_t count, loff_t *ppos)
15562306a36Sopenharmony_ci{
15662306a36Sopenharmony_ci	struct adis16475 *st = file->private_data;
15762306a36Sopenharmony_ci	u16 md, year;
15862306a36Sopenharmony_ci	char buf[12];
15962306a36Sopenharmony_ci	size_t len;
16062306a36Sopenharmony_ci	int ret;
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_ci	ret = adis_read_reg_16(&st->adis, ADIS16475_REG_FIRM_Y, &year);
16362306a36Sopenharmony_ci	if (ret)
16462306a36Sopenharmony_ci		return ret;
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci	ret = adis_read_reg_16(&st->adis, ADIS16475_REG_FIRM_DM, &md);
16762306a36Sopenharmony_ci	if (ret)
16862306a36Sopenharmony_ci		return ret;
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci	len = snprintf(buf, sizeof(buf), "%.2x-%.2x-%.4x\n", md >> 8, md & 0xff,
17162306a36Sopenharmony_ci		       year);
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci	return simple_read_from_buffer(userbuf, count, ppos, buf, len);
17462306a36Sopenharmony_ci}
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_cistatic const struct file_operations adis16475_firmware_date_fops = {
17762306a36Sopenharmony_ci	.open = simple_open,
17862306a36Sopenharmony_ci	.read = adis16475_show_firmware_date,
17962306a36Sopenharmony_ci	.llseek = default_llseek,
18062306a36Sopenharmony_ci	.owner = THIS_MODULE,
18162306a36Sopenharmony_ci};
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_cistatic int adis16475_show_serial_number(void *arg, u64 *val)
18462306a36Sopenharmony_ci{
18562306a36Sopenharmony_ci	struct adis16475 *st = arg;
18662306a36Sopenharmony_ci	u16 serial;
18762306a36Sopenharmony_ci	int ret;
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ci	ret = adis_read_reg_16(&st->adis, ADIS16475_REG_SERIAL_NUM, &serial);
19062306a36Sopenharmony_ci	if (ret)
19162306a36Sopenharmony_ci		return ret;
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci	*val = serial;
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci	return 0;
19662306a36Sopenharmony_ci}
19762306a36Sopenharmony_ciDEFINE_DEBUGFS_ATTRIBUTE(adis16475_serial_number_fops,
19862306a36Sopenharmony_ci			 adis16475_show_serial_number, NULL, "0x%.4llx\n");
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_cistatic int adis16475_show_product_id(void *arg, u64 *val)
20162306a36Sopenharmony_ci{
20262306a36Sopenharmony_ci	struct adis16475 *st = arg;
20362306a36Sopenharmony_ci	u16 prod_id;
20462306a36Sopenharmony_ci	int ret;
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ci	ret = adis_read_reg_16(&st->adis, ADIS16475_REG_PROD_ID, &prod_id);
20762306a36Sopenharmony_ci	if (ret)
20862306a36Sopenharmony_ci		return ret;
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ci	*val = prod_id;
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci	return 0;
21362306a36Sopenharmony_ci}
21462306a36Sopenharmony_ciDEFINE_DEBUGFS_ATTRIBUTE(adis16475_product_id_fops,
21562306a36Sopenharmony_ci			 adis16475_show_product_id, NULL, "%llu\n");
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_cistatic int adis16475_show_flash_count(void *arg, u64 *val)
21862306a36Sopenharmony_ci{
21962306a36Sopenharmony_ci	struct adis16475 *st = arg;
22062306a36Sopenharmony_ci	u32 flash_count;
22162306a36Sopenharmony_ci	int ret;
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci	ret = adis_read_reg_32(&st->adis, ADIS16475_REG_FLASH_CNT,
22462306a36Sopenharmony_ci			       &flash_count);
22562306a36Sopenharmony_ci	if (ret)
22662306a36Sopenharmony_ci		return ret;
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ci	*val = flash_count;
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci	return 0;
23162306a36Sopenharmony_ci}
23262306a36Sopenharmony_ciDEFINE_DEBUGFS_ATTRIBUTE(adis16475_flash_count_fops,
23362306a36Sopenharmony_ci			 adis16475_show_flash_count, NULL, "%lld\n");
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_cistatic void adis16475_debugfs_init(struct iio_dev *indio_dev)
23662306a36Sopenharmony_ci{
23762306a36Sopenharmony_ci	struct adis16475 *st = iio_priv(indio_dev);
23862306a36Sopenharmony_ci	struct dentry *d = iio_get_debugfs_dentry(indio_dev);
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ci	debugfs_create_file_unsafe("serial_number", 0400,
24162306a36Sopenharmony_ci				   d, st, &adis16475_serial_number_fops);
24262306a36Sopenharmony_ci	debugfs_create_file_unsafe("product_id", 0400,
24362306a36Sopenharmony_ci				   d, st, &adis16475_product_id_fops);
24462306a36Sopenharmony_ci	debugfs_create_file_unsafe("flash_count", 0400,
24562306a36Sopenharmony_ci				   d, st, &adis16475_flash_count_fops);
24662306a36Sopenharmony_ci	debugfs_create_file("firmware_revision", 0400,
24762306a36Sopenharmony_ci			    d, st, &adis16475_firmware_revision_fops);
24862306a36Sopenharmony_ci	debugfs_create_file("firmware_date", 0400, d,
24962306a36Sopenharmony_ci			    st, &adis16475_firmware_date_fops);
25062306a36Sopenharmony_ci}
25162306a36Sopenharmony_ci#else
25262306a36Sopenharmony_cistatic void adis16475_debugfs_init(struct iio_dev *indio_dev)
25362306a36Sopenharmony_ci{
25462306a36Sopenharmony_ci}
25562306a36Sopenharmony_ci#endif
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_cistatic int adis16475_get_freq(struct adis16475 *st, u32 *freq)
25862306a36Sopenharmony_ci{
25962306a36Sopenharmony_ci	int ret;
26062306a36Sopenharmony_ci	u16 dec;
26162306a36Sopenharmony_ci	u32 sample_rate = st->clk_freq;
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_ci	adis_dev_lock(&st->adis);
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci	if (st->sync_mode == ADIS16475_SYNC_SCALED) {
26662306a36Sopenharmony_ci		u16 sync_scale;
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci		ret = __adis_read_reg_16(&st->adis, ADIS16475_REG_UP_SCALE, &sync_scale);
26962306a36Sopenharmony_ci		if (ret)
27062306a36Sopenharmony_ci			goto error;
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_ci		sample_rate = st->clk_freq * sync_scale;
27362306a36Sopenharmony_ci	}
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci	ret = __adis_read_reg_16(&st->adis, ADIS16475_REG_DEC_RATE, &dec);
27662306a36Sopenharmony_ci	if (ret)
27762306a36Sopenharmony_ci		goto error;
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_ci	adis_dev_unlock(&st->adis);
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci	*freq = DIV_ROUND_CLOSEST(sample_rate, dec + 1);
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_ci	return 0;
28462306a36Sopenharmony_cierror:
28562306a36Sopenharmony_ci	adis_dev_unlock(&st->adis);
28662306a36Sopenharmony_ci	return ret;
28762306a36Sopenharmony_ci}
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_cistatic int adis16475_set_freq(struct adis16475 *st, const u32 freq)
29062306a36Sopenharmony_ci{
29162306a36Sopenharmony_ci	u16 dec;
29262306a36Sopenharmony_ci	int ret;
29362306a36Sopenharmony_ci	u32 sample_rate = st->clk_freq;
29462306a36Sopenharmony_ci
29562306a36Sopenharmony_ci	if (!freq)
29662306a36Sopenharmony_ci		return -EINVAL;
29762306a36Sopenharmony_ci
29862306a36Sopenharmony_ci	adis_dev_lock(&st->adis);
29962306a36Sopenharmony_ci	/*
30062306a36Sopenharmony_ci	 * When using sync scaled mode, the input clock needs to be scaled so that we have
30162306a36Sopenharmony_ci	 * an IMU sample rate between (optimally) 1900 and 2100. After this, we can use the
30262306a36Sopenharmony_ci	 * decimation filter to lower the sampling rate in order to get what the user wants.
30362306a36Sopenharmony_ci	 * Optimally, the user sample rate is a multiple of both the IMU sample rate and
30462306a36Sopenharmony_ci	 * the input clock. Hence, calculating the sync_scale dynamically gives us better
30562306a36Sopenharmony_ci	 * chances of achieving a perfect/integer value for DEC_RATE. The math here is:
30662306a36Sopenharmony_ci	 *	1. lcm of the input clock and the desired output rate.
30762306a36Sopenharmony_ci	 *	2. get the highest multiple of the previous result lower than the adis max rate.
30862306a36Sopenharmony_ci	 *	3. The last result becomes the IMU sample rate. Use that to calculate SYNC_SCALE
30962306a36Sopenharmony_ci	 *	   and DEC_RATE (to get the user output rate)
31062306a36Sopenharmony_ci	 */
31162306a36Sopenharmony_ci	if (st->sync_mode == ADIS16475_SYNC_SCALED) {
31262306a36Sopenharmony_ci		unsigned long scaled_rate = lcm(st->clk_freq, freq);
31362306a36Sopenharmony_ci		int sync_scale;
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_ci		/*
31662306a36Sopenharmony_ci		 * If lcm is bigger than the IMU maximum sampling rate there's no perfect
31762306a36Sopenharmony_ci		 * solution. In this case, we get the highest multiple of the input clock
31862306a36Sopenharmony_ci		 * lower than the IMU max sample rate.
31962306a36Sopenharmony_ci		 */
32062306a36Sopenharmony_ci		if (scaled_rate > 2100000)
32162306a36Sopenharmony_ci			scaled_rate = 2100000 / st->clk_freq * st->clk_freq;
32262306a36Sopenharmony_ci		else
32362306a36Sopenharmony_ci			scaled_rate = 2100000 / scaled_rate * scaled_rate;
32462306a36Sopenharmony_ci
32562306a36Sopenharmony_ci		/*
32662306a36Sopenharmony_ci		 * This is not an hard requirement but it's not advised to run the IMU
32762306a36Sopenharmony_ci		 * with a sample rate lower than 1900Hz due to possible undersampling
32862306a36Sopenharmony_ci		 * issues. However, there are users that might really want to take the risk.
32962306a36Sopenharmony_ci		 * Hence, we provide a module parameter for them. If set, we allow sample
33062306a36Sopenharmony_ci		 * rates lower than 1.9KHz. By default, we won't allow this and we just roundup
33162306a36Sopenharmony_ci		 * the rate to the next multiple of the input clock bigger than 1.9KHz. This
33262306a36Sopenharmony_ci		 * is done like this as in some cases (when DEC_RATE is 0) might give
33362306a36Sopenharmony_ci		 * us the closest value to the one desired by the user...
33462306a36Sopenharmony_ci		 */
33562306a36Sopenharmony_ci		if (scaled_rate < 1900000 && !low_rate_allow)
33662306a36Sopenharmony_ci			scaled_rate = roundup(1900000, st->clk_freq);
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_ci		sync_scale = scaled_rate / st->clk_freq;
33962306a36Sopenharmony_ci		ret = __adis_write_reg_16(&st->adis, ADIS16475_REG_UP_SCALE, sync_scale);
34062306a36Sopenharmony_ci		if (ret)
34162306a36Sopenharmony_ci			goto error;
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_ci		sample_rate = scaled_rate;
34462306a36Sopenharmony_ci	}
34562306a36Sopenharmony_ci
34662306a36Sopenharmony_ci	dec = DIV_ROUND_CLOSEST(sample_rate, freq);
34762306a36Sopenharmony_ci
34862306a36Sopenharmony_ci	if (dec)
34962306a36Sopenharmony_ci		dec--;
35062306a36Sopenharmony_ci
35162306a36Sopenharmony_ci	if (dec > st->info->max_dec)
35262306a36Sopenharmony_ci		dec = st->info->max_dec;
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ci	ret = __adis_write_reg_16(&st->adis, ADIS16475_REG_DEC_RATE, dec);
35562306a36Sopenharmony_ci	if (ret)
35662306a36Sopenharmony_ci		goto error;
35762306a36Sopenharmony_ci
35862306a36Sopenharmony_ci	adis_dev_unlock(&st->adis);
35962306a36Sopenharmony_ci	/*
36062306a36Sopenharmony_ci	 * If decimation is used, then gyro and accel data will have meaningful
36162306a36Sopenharmony_ci	 * bits on the LSB registers. This info is used on the trigger handler.
36262306a36Sopenharmony_ci	 */
36362306a36Sopenharmony_ci	assign_bit(ADIS16475_LSB_DEC_MASK, &st->lsb_flag, dec);
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_ci	return 0;
36662306a36Sopenharmony_cierror:
36762306a36Sopenharmony_ci	adis_dev_unlock(&st->adis);
36862306a36Sopenharmony_ci	return ret;
36962306a36Sopenharmony_ci}
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_ci/* The values are approximated. */
37262306a36Sopenharmony_cistatic const u32 adis16475_3db_freqs[] = {
37362306a36Sopenharmony_ci	[0] = 720, /* Filter disabled, full BW (~720Hz) */
37462306a36Sopenharmony_ci	[1] = 360,
37562306a36Sopenharmony_ci	[2] = 164,
37662306a36Sopenharmony_ci	[3] = 80,
37762306a36Sopenharmony_ci	[4] = 40,
37862306a36Sopenharmony_ci	[5] = 20,
37962306a36Sopenharmony_ci	[6] = 10,
38062306a36Sopenharmony_ci};
38162306a36Sopenharmony_ci
38262306a36Sopenharmony_cistatic int adis16475_get_filter(struct adis16475 *st, u32 *filter)
38362306a36Sopenharmony_ci{
38462306a36Sopenharmony_ci	u16 filter_sz;
38562306a36Sopenharmony_ci	int ret;
38662306a36Sopenharmony_ci	const int mask = ADIS16475_FILT_CTRL_MASK;
38762306a36Sopenharmony_ci
38862306a36Sopenharmony_ci	ret = adis_read_reg_16(&st->adis, ADIS16475_REG_FILT_CTRL, &filter_sz);
38962306a36Sopenharmony_ci	if (ret)
39062306a36Sopenharmony_ci		return ret;
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_ci	*filter = adis16475_3db_freqs[filter_sz & mask];
39362306a36Sopenharmony_ci
39462306a36Sopenharmony_ci	return 0;
39562306a36Sopenharmony_ci}
39662306a36Sopenharmony_ci
39762306a36Sopenharmony_cistatic int adis16475_set_filter(struct adis16475 *st, const u32 filter)
39862306a36Sopenharmony_ci{
39962306a36Sopenharmony_ci	int i = ARRAY_SIZE(adis16475_3db_freqs);
40062306a36Sopenharmony_ci	int ret;
40162306a36Sopenharmony_ci
40262306a36Sopenharmony_ci	while (--i) {
40362306a36Sopenharmony_ci		if (adis16475_3db_freqs[i] >= filter)
40462306a36Sopenharmony_ci			break;
40562306a36Sopenharmony_ci	}
40662306a36Sopenharmony_ci
40762306a36Sopenharmony_ci	ret = adis_write_reg_16(&st->adis, ADIS16475_REG_FILT_CTRL,
40862306a36Sopenharmony_ci				ADIS16475_FILT_CTRL(i));
40962306a36Sopenharmony_ci	if (ret)
41062306a36Sopenharmony_ci		return ret;
41162306a36Sopenharmony_ci
41262306a36Sopenharmony_ci	/*
41362306a36Sopenharmony_ci	 * If FIR is used, then gyro and accel data will have meaningful
41462306a36Sopenharmony_ci	 * bits on the LSB registers. This info is used on the trigger handler.
41562306a36Sopenharmony_ci	 */
41662306a36Sopenharmony_ci	assign_bit(ADIS16475_LSB_FIR_MASK, &st->lsb_flag, i);
41762306a36Sopenharmony_ci
41862306a36Sopenharmony_ci	return 0;
41962306a36Sopenharmony_ci}
42062306a36Sopenharmony_ci
42162306a36Sopenharmony_cistatic const u32 adis16475_calib_regs[] = {
42262306a36Sopenharmony_ci	[ADIS16475_SCAN_GYRO_X] = ADIS16475_REG_X_GYRO_BIAS_L,
42362306a36Sopenharmony_ci	[ADIS16475_SCAN_GYRO_Y] = ADIS16475_REG_Y_GYRO_BIAS_L,
42462306a36Sopenharmony_ci	[ADIS16475_SCAN_GYRO_Z] = ADIS16475_REG_Z_GYRO_BIAS_L,
42562306a36Sopenharmony_ci	[ADIS16475_SCAN_ACCEL_X] = ADIS16475_REG_X_ACCEL_BIAS_L,
42662306a36Sopenharmony_ci	[ADIS16475_SCAN_ACCEL_Y] = ADIS16475_REG_Y_ACCEL_BIAS_L,
42762306a36Sopenharmony_ci	[ADIS16475_SCAN_ACCEL_Z] = ADIS16475_REG_Z_ACCEL_BIAS_L,
42862306a36Sopenharmony_ci};
42962306a36Sopenharmony_ci
43062306a36Sopenharmony_cistatic int adis16475_read_raw(struct iio_dev *indio_dev,
43162306a36Sopenharmony_ci			      const struct iio_chan_spec *chan,
43262306a36Sopenharmony_ci			      int *val, int *val2, long info)
43362306a36Sopenharmony_ci{
43462306a36Sopenharmony_ci	struct adis16475 *st = iio_priv(indio_dev);
43562306a36Sopenharmony_ci	int ret;
43662306a36Sopenharmony_ci	u32 tmp;
43762306a36Sopenharmony_ci
43862306a36Sopenharmony_ci	switch (info) {
43962306a36Sopenharmony_ci	case IIO_CHAN_INFO_RAW:
44062306a36Sopenharmony_ci		return adis_single_conversion(indio_dev, chan, 0, val);
44162306a36Sopenharmony_ci	case IIO_CHAN_INFO_SCALE:
44262306a36Sopenharmony_ci		switch (chan->type) {
44362306a36Sopenharmony_ci		case IIO_ANGL_VEL:
44462306a36Sopenharmony_ci			*val = st->info->gyro_max_val;
44562306a36Sopenharmony_ci			*val2 = st->info->gyro_max_scale;
44662306a36Sopenharmony_ci			return IIO_VAL_FRACTIONAL;
44762306a36Sopenharmony_ci		case IIO_ACCEL:
44862306a36Sopenharmony_ci			*val = st->info->accel_max_val;
44962306a36Sopenharmony_ci			*val2 = st->info->accel_max_scale;
45062306a36Sopenharmony_ci			return IIO_VAL_FRACTIONAL;
45162306a36Sopenharmony_ci		case IIO_TEMP:
45262306a36Sopenharmony_ci			*val = st->info->temp_scale;
45362306a36Sopenharmony_ci			return IIO_VAL_INT;
45462306a36Sopenharmony_ci		default:
45562306a36Sopenharmony_ci			return -EINVAL;
45662306a36Sopenharmony_ci		}
45762306a36Sopenharmony_ci	case IIO_CHAN_INFO_CALIBBIAS:
45862306a36Sopenharmony_ci		ret = adis_read_reg_32(&st->adis,
45962306a36Sopenharmony_ci				       adis16475_calib_regs[chan->scan_index],
46062306a36Sopenharmony_ci				       val);
46162306a36Sopenharmony_ci		if (ret)
46262306a36Sopenharmony_ci			return ret;
46362306a36Sopenharmony_ci
46462306a36Sopenharmony_ci		return IIO_VAL_INT;
46562306a36Sopenharmony_ci	case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
46662306a36Sopenharmony_ci		ret = adis16475_get_filter(st, val);
46762306a36Sopenharmony_ci		if (ret)
46862306a36Sopenharmony_ci			return ret;
46962306a36Sopenharmony_ci
47062306a36Sopenharmony_ci		return IIO_VAL_INT;
47162306a36Sopenharmony_ci	case IIO_CHAN_INFO_SAMP_FREQ:
47262306a36Sopenharmony_ci		ret = adis16475_get_freq(st, &tmp);
47362306a36Sopenharmony_ci		if (ret)
47462306a36Sopenharmony_ci			return ret;
47562306a36Sopenharmony_ci
47662306a36Sopenharmony_ci		*val = tmp / 1000;
47762306a36Sopenharmony_ci		*val2 = (tmp % 1000) * 1000;
47862306a36Sopenharmony_ci		return IIO_VAL_INT_PLUS_MICRO;
47962306a36Sopenharmony_ci	default:
48062306a36Sopenharmony_ci		return -EINVAL;
48162306a36Sopenharmony_ci	}
48262306a36Sopenharmony_ci}
48362306a36Sopenharmony_ci
48462306a36Sopenharmony_cistatic int adis16475_write_raw(struct iio_dev *indio_dev,
48562306a36Sopenharmony_ci			       const struct iio_chan_spec *chan,
48662306a36Sopenharmony_ci			       int val, int val2, long info)
48762306a36Sopenharmony_ci{
48862306a36Sopenharmony_ci	struct adis16475 *st = iio_priv(indio_dev);
48962306a36Sopenharmony_ci	u32 tmp;
49062306a36Sopenharmony_ci
49162306a36Sopenharmony_ci	switch (info) {
49262306a36Sopenharmony_ci	case IIO_CHAN_INFO_SAMP_FREQ:
49362306a36Sopenharmony_ci		tmp = val * 1000 + val2 / 1000;
49462306a36Sopenharmony_ci		return adis16475_set_freq(st, tmp);
49562306a36Sopenharmony_ci	case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
49662306a36Sopenharmony_ci		return adis16475_set_filter(st, val);
49762306a36Sopenharmony_ci	case IIO_CHAN_INFO_CALIBBIAS:
49862306a36Sopenharmony_ci		return adis_write_reg_32(&st->adis,
49962306a36Sopenharmony_ci					 adis16475_calib_regs[chan->scan_index],
50062306a36Sopenharmony_ci					 val);
50162306a36Sopenharmony_ci	default:
50262306a36Sopenharmony_ci		return -EINVAL;
50362306a36Sopenharmony_ci	}
50462306a36Sopenharmony_ci}
50562306a36Sopenharmony_ci
50662306a36Sopenharmony_ci#define ADIS16475_MOD_CHAN(_type, _mod, _address, _si, _r_bits, _s_bits) \
50762306a36Sopenharmony_ci	{ \
50862306a36Sopenharmony_ci		.type = (_type), \
50962306a36Sopenharmony_ci		.modified = 1, \
51062306a36Sopenharmony_ci		.channel2 = (_mod), \
51162306a36Sopenharmony_ci		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
51262306a36Sopenharmony_ci			BIT(IIO_CHAN_INFO_CALIBBIAS), \
51362306a36Sopenharmony_ci		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
51462306a36Sopenharmony_ci		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
51562306a36Sopenharmony_ci			BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \
51662306a36Sopenharmony_ci		.address = (_address), \
51762306a36Sopenharmony_ci		.scan_index = (_si), \
51862306a36Sopenharmony_ci		.scan_type = { \
51962306a36Sopenharmony_ci			.sign = 's', \
52062306a36Sopenharmony_ci			.realbits = (_r_bits), \
52162306a36Sopenharmony_ci			.storagebits = (_s_bits), \
52262306a36Sopenharmony_ci			.endianness = IIO_BE, \
52362306a36Sopenharmony_ci		}, \
52462306a36Sopenharmony_ci	}
52562306a36Sopenharmony_ci
52662306a36Sopenharmony_ci#define ADIS16475_GYRO_CHANNEL(_mod) \
52762306a36Sopenharmony_ci	ADIS16475_MOD_CHAN(IIO_ANGL_VEL, IIO_MOD_ ## _mod, \
52862306a36Sopenharmony_ci			   ADIS16475_REG_ ## _mod ## _GYRO_L, \
52962306a36Sopenharmony_ci			   ADIS16475_SCAN_GYRO_ ## _mod, 32, 32)
53062306a36Sopenharmony_ci
53162306a36Sopenharmony_ci#define ADIS16475_ACCEL_CHANNEL(_mod) \
53262306a36Sopenharmony_ci	ADIS16475_MOD_CHAN(IIO_ACCEL, IIO_MOD_ ## _mod, \
53362306a36Sopenharmony_ci			   ADIS16475_REG_ ## _mod ## _ACCEL_L, \
53462306a36Sopenharmony_ci			   ADIS16475_SCAN_ACCEL_ ## _mod, 32, 32)
53562306a36Sopenharmony_ci
53662306a36Sopenharmony_ci#define ADIS16475_TEMP_CHANNEL() { \
53762306a36Sopenharmony_ci		.type = IIO_TEMP, \
53862306a36Sopenharmony_ci		.indexed = 1, \
53962306a36Sopenharmony_ci		.channel = 0, \
54062306a36Sopenharmony_ci		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
54162306a36Sopenharmony_ci			BIT(IIO_CHAN_INFO_SCALE), \
54262306a36Sopenharmony_ci		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
54362306a36Sopenharmony_ci			BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \
54462306a36Sopenharmony_ci		.address = ADIS16475_REG_TEMP_OUT, \
54562306a36Sopenharmony_ci		.scan_index = ADIS16475_SCAN_TEMP, \
54662306a36Sopenharmony_ci		.scan_type = { \
54762306a36Sopenharmony_ci			.sign = 's', \
54862306a36Sopenharmony_ci			.realbits = 16, \
54962306a36Sopenharmony_ci			.storagebits = 16, \
55062306a36Sopenharmony_ci			.endianness = IIO_BE, \
55162306a36Sopenharmony_ci		}, \
55262306a36Sopenharmony_ci	}
55362306a36Sopenharmony_ci
55462306a36Sopenharmony_cistatic const struct iio_chan_spec adis16475_channels[] = {
55562306a36Sopenharmony_ci	ADIS16475_GYRO_CHANNEL(X),
55662306a36Sopenharmony_ci	ADIS16475_GYRO_CHANNEL(Y),
55762306a36Sopenharmony_ci	ADIS16475_GYRO_CHANNEL(Z),
55862306a36Sopenharmony_ci	ADIS16475_ACCEL_CHANNEL(X),
55962306a36Sopenharmony_ci	ADIS16475_ACCEL_CHANNEL(Y),
56062306a36Sopenharmony_ci	ADIS16475_ACCEL_CHANNEL(Z),
56162306a36Sopenharmony_ci	ADIS16475_TEMP_CHANNEL(),
56262306a36Sopenharmony_ci	IIO_CHAN_SOFT_TIMESTAMP(7)
56362306a36Sopenharmony_ci};
56462306a36Sopenharmony_ci
56562306a36Sopenharmony_cienum adis16475_variant {
56662306a36Sopenharmony_ci	ADIS16470,
56762306a36Sopenharmony_ci	ADIS16475_1,
56862306a36Sopenharmony_ci	ADIS16475_2,
56962306a36Sopenharmony_ci	ADIS16475_3,
57062306a36Sopenharmony_ci	ADIS16477_1,
57162306a36Sopenharmony_ci	ADIS16477_2,
57262306a36Sopenharmony_ci	ADIS16477_3,
57362306a36Sopenharmony_ci	ADIS16465_1,
57462306a36Sopenharmony_ci	ADIS16465_2,
57562306a36Sopenharmony_ci	ADIS16465_3,
57662306a36Sopenharmony_ci	ADIS16467_1,
57762306a36Sopenharmony_ci	ADIS16467_2,
57862306a36Sopenharmony_ci	ADIS16467_3,
57962306a36Sopenharmony_ci	ADIS16500,
58062306a36Sopenharmony_ci	ADIS16505_1,
58162306a36Sopenharmony_ci	ADIS16505_2,
58262306a36Sopenharmony_ci	ADIS16505_3,
58362306a36Sopenharmony_ci	ADIS16507_1,
58462306a36Sopenharmony_ci	ADIS16507_2,
58562306a36Sopenharmony_ci	ADIS16507_3,
58662306a36Sopenharmony_ci};
58762306a36Sopenharmony_ci
58862306a36Sopenharmony_cienum {
58962306a36Sopenharmony_ci	ADIS16475_DIAG_STAT_DATA_PATH = 1,
59062306a36Sopenharmony_ci	ADIS16475_DIAG_STAT_FLASH_MEM,
59162306a36Sopenharmony_ci	ADIS16475_DIAG_STAT_SPI,
59262306a36Sopenharmony_ci	ADIS16475_DIAG_STAT_STANDBY,
59362306a36Sopenharmony_ci	ADIS16475_DIAG_STAT_SENSOR,
59462306a36Sopenharmony_ci	ADIS16475_DIAG_STAT_MEMORY,
59562306a36Sopenharmony_ci	ADIS16475_DIAG_STAT_CLK,
59662306a36Sopenharmony_ci};
59762306a36Sopenharmony_ci
59862306a36Sopenharmony_cistatic const char * const adis16475_status_error_msgs[] = {
59962306a36Sopenharmony_ci	[ADIS16475_DIAG_STAT_DATA_PATH] = "Data Path Overrun",
60062306a36Sopenharmony_ci	[ADIS16475_DIAG_STAT_FLASH_MEM] = "Flash memory update failure",
60162306a36Sopenharmony_ci	[ADIS16475_DIAG_STAT_SPI] = "SPI communication error",
60262306a36Sopenharmony_ci	[ADIS16475_DIAG_STAT_STANDBY] = "Standby mode",
60362306a36Sopenharmony_ci	[ADIS16475_DIAG_STAT_SENSOR] = "Sensor failure",
60462306a36Sopenharmony_ci	[ADIS16475_DIAG_STAT_MEMORY] = "Memory failure",
60562306a36Sopenharmony_ci	[ADIS16475_DIAG_STAT_CLK] = "Clock error",
60662306a36Sopenharmony_ci};
60762306a36Sopenharmony_ci
60862306a36Sopenharmony_ci#define ADIS16475_DATA(_prod_id, _timeouts)				\
60962306a36Sopenharmony_ci{									\
61062306a36Sopenharmony_ci	.msc_ctrl_reg = ADIS16475_REG_MSG_CTRL,				\
61162306a36Sopenharmony_ci	.glob_cmd_reg = ADIS16475_REG_GLOB_CMD,				\
61262306a36Sopenharmony_ci	.diag_stat_reg = ADIS16475_REG_DIAG_STAT,			\
61362306a36Sopenharmony_ci	.prod_id_reg = ADIS16475_REG_PROD_ID,				\
61462306a36Sopenharmony_ci	.prod_id = (_prod_id),						\
61562306a36Sopenharmony_ci	.self_test_mask = BIT(2),					\
61662306a36Sopenharmony_ci	.self_test_reg = ADIS16475_REG_GLOB_CMD,			\
61762306a36Sopenharmony_ci	.cs_change_delay = 16,						\
61862306a36Sopenharmony_ci	.read_delay = 5,						\
61962306a36Sopenharmony_ci	.write_delay = 5,						\
62062306a36Sopenharmony_ci	.status_error_msgs = adis16475_status_error_msgs,		\
62162306a36Sopenharmony_ci	.status_error_mask = BIT(ADIS16475_DIAG_STAT_DATA_PATH) |	\
62262306a36Sopenharmony_ci		BIT(ADIS16475_DIAG_STAT_FLASH_MEM) |			\
62362306a36Sopenharmony_ci		BIT(ADIS16475_DIAG_STAT_SPI) |				\
62462306a36Sopenharmony_ci		BIT(ADIS16475_DIAG_STAT_STANDBY) |			\
62562306a36Sopenharmony_ci		BIT(ADIS16475_DIAG_STAT_SENSOR) |			\
62662306a36Sopenharmony_ci		BIT(ADIS16475_DIAG_STAT_MEMORY) |			\
62762306a36Sopenharmony_ci		BIT(ADIS16475_DIAG_STAT_CLK),				\
62862306a36Sopenharmony_ci	.unmasked_drdy = true,						\
62962306a36Sopenharmony_ci	.timeouts = (_timeouts),					\
63062306a36Sopenharmony_ci	.burst_reg_cmd = ADIS16475_REG_GLOB_CMD,			\
63162306a36Sopenharmony_ci	.burst_len = ADIS16475_BURST_MAX_DATA,				\
63262306a36Sopenharmony_ci	.burst_max_len = ADIS16475_BURST32_MAX_DATA,			\
63362306a36Sopenharmony_ci	.burst_max_speed_hz = ADIS16475_BURST_MAX_SPEED			\
63462306a36Sopenharmony_ci}
63562306a36Sopenharmony_ci
63662306a36Sopenharmony_cistatic const struct adis16475_sync adis16475_sync_mode[] = {
63762306a36Sopenharmony_ci	{ ADIS16475_SYNC_OUTPUT },
63862306a36Sopenharmony_ci	{ ADIS16475_SYNC_DIRECT, 1900, 2100 },
63962306a36Sopenharmony_ci	{ ADIS16475_SYNC_SCALED, 1, 128 },
64062306a36Sopenharmony_ci	{ ADIS16475_SYNC_PULSE, 1000, 2100 },
64162306a36Sopenharmony_ci};
64262306a36Sopenharmony_ci
64362306a36Sopenharmony_cistatic const struct adis_timeout adis16475_timeouts = {
64462306a36Sopenharmony_ci	.reset_ms = 200,
64562306a36Sopenharmony_ci	.sw_reset_ms = 200,
64662306a36Sopenharmony_ci	.self_test_ms = 20,
64762306a36Sopenharmony_ci};
64862306a36Sopenharmony_ci
64962306a36Sopenharmony_cistatic const struct adis_timeout adis1650x_timeouts = {
65062306a36Sopenharmony_ci	.reset_ms = 260,
65162306a36Sopenharmony_ci	.sw_reset_ms = 260,
65262306a36Sopenharmony_ci	.self_test_ms = 30,
65362306a36Sopenharmony_ci};
65462306a36Sopenharmony_ci
65562306a36Sopenharmony_cistatic const struct adis16475_chip_info adis16475_chip_info[] = {
65662306a36Sopenharmony_ci	[ADIS16470] = {
65762306a36Sopenharmony_ci		.name = "adis16470",
65862306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(adis16475_channels),
65962306a36Sopenharmony_ci		.channels = adis16475_channels,
66062306a36Sopenharmony_ci		.gyro_max_val = 1,
66162306a36Sopenharmony_ci		.gyro_max_scale = IIO_RAD_TO_DEGREE(10 << 16),
66262306a36Sopenharmony_ci		.accel_max_val = 1,
66362306a36Sopenharmony_ci		.accel_max_scale = IIO_M_S_2_TO_G(800 << 16),
66462306a36Sopenharmony_ci		.temp_scale = 100,
66562306a36Sopenharmony_ci		.int_clk = 2000,
66662306a36Sopenharmony_ci		.max_dec = 1999,
66762306a36Sopenharmony_ci		.sync = adis16475_sync_mode,
66862306a36Sopenharmony_ci		.num_sync = ARRAY_SIZE(adis16475_sync_mode),
66962306a36Sopenharmony_ci		.adis_data = ADIS16475_DATA(16470, &adis16475_timeouts),
67062306a36Sopenharmony_ci	},
67162306a36Sopenharmony_ci	[ADIS16475_1] = {
67262306a36Sopenharmony_ci		.name = "adis16475-1",
67362306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(adis16475_channels),
67462306a36Sopenharmony_ci		.channels = adis16475_channels,
67562306a36Sopenharmony_ci		.gyro_max_val = 1,
67662306a36Sopenharmony_ci		.gyro_max_scale = IIO_RAD_TO_DEGREE(160 << 16),
67762306a36Sopenharmony_ci		.accel_max_val = 1,
67862306a36Sopenharmony_ci		.accel_max_scale = IIO_M_S_2_TO_G(4000 << 16),
67962306a36Sopenharmony_ci		.temp_scale = 100,
68062306a36Sopenharmony_ci		.int_clk = 2000,
68162306a36Sopenharmony_ci		.max_dec = 1999,
68262306a36Sopenharmony_ci		.sync = adis16475_sync_mode,
68362306a36Sopenharmony_ci		.num_sync = ARRAY_SIZE(adis16475_sync_mode),
68462306a36Sopenharmony_ci		.adis_data = ADIS16475_DATA(16475, &adis16475_timeouts),
68562306a36Sopenharmony_ci	},
68662306a36Sopenharmony_ci	[ADIS16475_2] = {
68762306a36Sopenharmony_ci		.name = "adis16475-2",
68862306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(adis16475_channels),
68962306a36Sopenharmony_ci		.channels = adis16475_channels,
69062306a36Sopenharmony_ci		.gyro_max_val = 1,
69162306a36Sopenharmony_ci		.gyro_max_scale = IIO_RAD_TO_DEGREE(40 << 16),
69262306a36Sopenharmony_ci		.accel_max_val = 1,
69362306a36Sopenharmony_ci		.accel_max_scale = IIO_M_S_2_TO_G(4000 << 16),
69462306a36Sopenharmony_ci		.temp_scale = 100,
69562306a36Sopenharmony_ci		.int_clk = 2000,
69662306a36Sopenharmony_ci		.max_dec = 1999,
69762306a36Sopenharmony_ci		.sync = adis16475_sync_mode,
69862306a36Sopenharmony_ci		.num_sync = ARRAY_SIZE(adis16475_sync_mode),
69962306a36Sopenharmony_ci		.adis_data = ADIS16475_DATA(16475, &adis16475_timeouts),
70062306a36Sopenharmony_ci	},
70162306a36Sopenharmony_ci	[ADIS16475_3] = {
70262306a36Sopenharmony_ci		.name = "adis16475-3",
70362306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(adis16475_channels),
70462306a36Sopenharmony_ci		.channels = adis16475_channels,
70562306a36Sopenharmony_ci		.gyro_max_val = 1,
70662306a36Sopenharmony_ci		.gyro_max_scale = IIO_RAD_TO_DEGREE(10 << 16),
70762306a36Sopenharmony_ci		.accel_max_val = 1,
70862306a36Sopenharmony_ci		.accel_max_scale = IIO_M_S_2_TO_G(4000 << 16),
70962306a36Sopenharmony_ci		.temp_scale = 100,
71062306a36Sopenharmony_ci		.int_clk = 2000,
71162306a36Sopenharmony_ci		.max_dec = 1999,
71262306a36Sopenharmony_ci		.sync = adis16475_sync_mode,
71362306a36Sopenharmony_ci		.num_sync = ARRAY_SIZE(adis16475_sync_mode),
71462306a36Sopenharmony_ci		.adis_data = ADIS16475_DATA(16475, &adis16475_timeouts),
71562306a36Sopenharmony_ci	},
71662306a36Sopenharmony_ci	[ADIS16477_1] = {
71762306a36Sopenharmony_ci		.name = "adis16477-1",
71862306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(adis16475_channels),
71962306a36Sopenharmony_ci		.channels = adis16475_channels,
72062306a36Sopenharmony_ci		.gyro_max_val = 1,
72162306a36Sopenharmony_ci		.gyro_max_scale = IIO_RAD_TO_DEGREE(160 << 16),
72262306a36Sopenharmony_ci		.accel_max_val = 1,
72362306a36Sopenharmony_ci		.accel_max_scale = IIO_M_S_2_TO_G(800 << 16),
72462306a36Sopenharmony_ci		.temp_scale = 100,
72562306a36Sopenharmony_ci		.int_clk = 2000,
72662306a36Sopenharmony_ci		.max_dec = 1999,
72762306a36Sopenharmony_ci		.sync = adis16475_sync_mode,
72862306a36Sopenharmony_ci		.num_sync = ARRAY_SIZE(adis16475_sync_mode),
72962306a36Sopenharmony_ci		.has_burst32 = true,
73062306a36Sopenharmony_ci		.adis_data = ADIS16475_DATA(16477, &adis16475_timeouts),
73162306a36Sopenharmony_ci	},
73262306a36Sopenharmony_ci	[ADIS16477_2] = {
73362306a36Sopenharmony_ci		.name = "adis16477-2",
73462306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(adis16475_channels),
73562306a36Sopenharmony_ci		.channels = adis16475_channels,
73662306a36Sopenharmony_ci		.gyro_max_val = 1,
73762306a36Sopenharmony_ci		.gyro_max_scale = IIO_RAD_TO_DEGREE(40 << 16),
73862306a36Sopenharmony_ci		.accel_max_val = 1,
73962306a36Sopenharmony_ci		.accel_max_scale = IIO_M_S_2_TO_G(800 << 16),
74062306a36Sopenharmony_ci		.temp_scale = 100,
74162306a36Sopenharmony_ci		.int_clk = 2000,
74262306a36Sopenharmony_ci		.max_dec = 1999,
74362306a36Sopenharmony_ci		.sync = adis16475_sync_mode,
74462306a36Sopenharmony_ci		.num_sync = ARRAY_SIZE(adis16475_sync_mode),
74562306a36Sopenharmony_ci		.has_burst32 = true,
74662306a36Sopenharmony_ci		.adis_data = ADIS16475_DATA(16477, &adis16475_timeouts),
74762306a36Sopenharmony_ci	},
74862306a36Sopenharmony_ci	[ADIS16477_3] = {
74962306a36Sopenharmony_ci		.name = "adis16477-3",
75062306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(adis16475_channels),
75162306a36Sopenharmony_ci		.channels = adis16475_channels,
75262306a36Sopenharmony_ci		.gyro_max_val = 1,
75362306a36Sopenharmony_ci		.gyro_max_scale = IIO_RAD_TO_DEGREE(10 << 16),
75462306a36Sopenharmony_ci		.accel_max_val = 1,
75562306a36Sopenharmony_ci		.accel_max_scale = IIO_M_S_2_TO_G(800 << 16),
75662306a36Sopenharmony_ci		.temp_scale = 100,
75762306a36Sopenharmony_ci		.int_clk = 2000,
75862306a36Sopenharmony_ci		.max_dec = 1999,
75962306a36Sopenharmony_ci		.sync = adis16475_sync_mode,
76062306a36Sopenharmony_ci		.num_sync = ARRAY_SIZE(adis16475_sync_mode),
76162306a36Sopenharmony_ci		.has_burst32 = true,
76262306a36Sopenharmony_ci		.adis_data = ADIS16475_DATA(16477, &adis16475_timeouts),
76362306a36Sopenharmony_ci	},
76462306a36Sopenharmony_ci	[ADIS16465_1] = {
76562306a36Sopenharmony_ci		.name = "adis16465-1",
76662306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(adis16475_channels),
76762306a36Sopenharmony_ci		.channels = adis16475_channels,
76862306a36Sopenharmony_ci		.gyro_max_val = 1,
76962306a36Sopenharmony_ci		.gyro_max_scale = IIO_RAD_TO_DEGREE(160 << 16),
77062306a36Sopenharmony_ci		.accel_max_val = 1,
77162306a36Sopenharmony_ci		.accel_max_scale = IIO_M_S_2_TO_G(4000 << 16),
77262306a36Sopenharmony_ci		.temp_scale = 100,
77362306a36Sopenharmony_ci		.int_clk = 2000,
77462306a36Sopenharmony_ci		.max_dec = 1999,
77562306a36Sopenharmony_ci		.sync = adis16475_sync_mode,
77662306a36Sopenharmony_ci		.num_sync = ARRAY_SIZE(adis16475_sync_mode),
77762306a36Sopenharmony_ci		.adis_data = ADIS16475_DATA(16465, &adis16475_timeouts),
77862306a36Sopenharmony_ci	},
77962306a36Sopenharmony_ci	[ADIS16465_2] = {
78062306a36Sopenharmony_ci		.name = "adis16465-2",
78162306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(adis16475_channels),
78262306a36Sopenharmony_ci		.channels = adis16475_channels,
78362306a36Sopenharmony_ci		.gyro_max_val = 1,
78462306a36Sopenharmony_ci		.gyro_max_scale = IIO_RAD_TO_DEGREE(40 << 16),
78562306a36Sopenharmony_ci		.accel_max_val = 1,
78662306a36Sopenharmony_ci		.accel_max_scale = IIO_M_S_2_TO_G(4000 << 16),
78762306a36Sopenharmony_ci		.temp_scale = 100,
78862306a36Sopenharmony_ci		.int_clk = 2000,
78962306a36Sopenharmony_ci		.max_dec = 1999,
79062306a36Sopenharmony_ci		.sync = adis16475_sync_mode,
79162306a36Sopenharmony_ci		.num_sync = ARRAY_SIZE(adis16475_sync_mode),
79262306a36Sopenharmony_ci		.adis_data = ADIS16475_DATA(16465, &adis16475_timeouts),
79362306a36Sopenharmony_ci	},
79462306a36Sopenharmony_ci	[ADIS16465_3] = {
79562306a36Sopenharmony_ci		.name = "adis16465-3",
79662306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(adis16475_channels),
79762306a36Sopenharmony_ci		.channels = adis16475_channels,
79862306a36Sopenharmony_ci		.gyro_max_val = 1,
79962306a36Sopenharmony_ci		.gyro_max_scale = IIO_RAD_TO_DEGREE(10 << 16),
80062306a36Sopenharmony_ci		.accel_max_val = 1,
80162306a36Sopenharmony_ci		.accel_max_scale = IIO_M_S_2_TO_G(4000 << 16),
80262306a36Sopenharmony_ci		.temp_scale = 100,
80362306a36Sopenharmony_ci		.int_clk = 2000,
80462306a36Sopenharmony_ci		.max_dec = 1999,
80562306a36Sopenharmony_ci		.sync = adis16475_sync_mode,
80662306a36Sopenharmony_ci		.num_sync = ARRAY_SIZE(adis16475_sync_mode),
80762306a36Sopenharmony_ci		.adis_data = ADIS16475_DATA(16465, &adis16475_timeouts),
80862306a36Sopenharmony_ci	},
80962306a36Sopenharmony_ci	[ADIS16467_1] = {
81062306a36Sopenharmony_ci		.name = "adis16467-1",
81162306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(adis16475_channels),
81262306a36Sopenharmony_ci		.channels = adis16475_channels,
81362306a36Sopenharmony_ci		.gyro_max_val = 1,
81462306a36Sopenharmony_ci		.gyro_max_scale = IIO_RAD_TO_DEGREE(160 << 16),
81562306a36Sopenharmony_ci		.accel_max_val = 1,
81662306a36Sopenharmony_ci		.accel_max_scale = IIO_M_S_2_TO_G(800 << 16),
81762306a36Sopenharmony_ci		.temp_scale = 100,
81862306a36Sopenharmony_ci		.int_clk = 2000,
81962306a36Sopenharmony_ci		.max_dec = 1999,
82062306a36Sopenharmony_ci		.sync = adis16475_sync_mode,
82162306a36Sopenharmony_ci		.num_sync = ARRAY_SIZE(adis16475_sync_mode),
82262306a36Sopenharmony_ci		.adis_data = ADIS16475_DATA(16467, &adis16475_timeouts),
82362306a36Sopenharmony_ci	},
82462306a36Sopenharmony_ci	[ADIS16467_2] = {
82562306a36Sopenharmony_ci		.name = "adis16467-2",
82662306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(adis16475_channels),
82762306a36Sopenharmony_ci		.channels = adis16475_channels,
82862306a36Sopenharmony_ci		.gyro_max_val = 1,
82962306a36Sopenharmony_ci		.gyro_max_scale = IIO_RAD_TO_DEGREE(40 << 16),
83062306a36Sopenharmony_ci		.accel_max_val = 1,
83162306a36Sopenharmony_ci		.accel_max_scale = IIO_M_S_2_TO_G(800 << 16),
83262306a36Sopenharmony_ci		.temp_scale = 100,
83362306a36Sopenharmony_ci		.int_clk = 2000,
83462306a36Sopenharmony_ci		.max_dec = 1999,
83562306a36Sopenharmony_ci		.sync = adis16475_sync_mode,
83662306a36Sopenharmony_ci		.num_sync = ARRAY_SIZE(adis16475_sync_mode),
83762306a36Sopenharmony_ci		.adis_data = ADIS16475_DATA(16467, &adis16475_timeouts),
83862306a36Sopenharmony_ci	},
83962306a36Sopenharmony_ci	[ADIS16467_3] = {
84062306a36Sopenharmony_ci		.name = "adis16467-3",
84162306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(adis16475_channels),
84262306a36Sopenharmony_ci		.channels = adis16475_channels,
84362306a36Sopenharmony_ci		.gyro_max_val = 1,
84462306a36Sopenharmony_ci		.gyro_max_scale = IIO_RAD_TO_DEGREE(10 << 16),
84562306a36Sopenharmony_ci		.accel_max_val = 1,
84662306a36Sopenharmony_ci		.accel_max_scale = IIO_M_S_2_TO_G(800 << 16),
84762306a36Sopenharmony_ci		.temp_scale = 100,
84862306a36Sopenharmony_ci		.int_clk = 2000,
84962306a36Sopenharmony_ci		.max_dec = 1999,
85062306a36Sopenharmony_ci		.sync = adis16475_sync_mode,
85162306a36Sopenharmony_ci		.num_sync = ARRAY_SIZE(adis16475_sync_mode),
85262306a36Sopenharmony_ci		.adis_data = ADIS16475_DATA(16467, &adis16475_timeouts),
85362306a36Sopenharmony_ci	},
85462306a36Sopenharmony_ci	[ADIS16500] = {
85562306a36Sopenharmony_ci		.name = "adis16500",
85662306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(adis16475_channels),
85762306a36Sopenharmony_ci		.channels = adis16475_channels,
85862306a36Sopenharmony_ci		.gyro_max_val = 1,
85962306a36Sopenharmony_ci		.gyro_max_scale = IIO_RAD_TO_DEGREE(10 << 16),
86062306a36Sopenharmony_ci		.accel_max_val = 392,
86162306a36Sopenharmony_ci		.accel_max_scale = 32000 << 16,
86262306a36Sopenharmony_ci		.temp_scale = 100,
86362306a36Sopenharmony_ci		.int_clk = 2000,
86462306a36Sopenharmony_ci		.max_dec = 1999,
86562306a36Sopenharmony_ci		.sync = adis16475_sync_mode,
86662306a36Sopenharmony_ci		/* pulse sync not supported */
86762306a36Sopenharmony_ci		.num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1,
86862306a36Sopenharmony_ci		.has_burst32 = true,
86962306a36Sopenharmony_ci		.adis_data = ADIS16475_DATA(16500, &adis1650x_timeouts),
87062306a36Sopenharmony_ci	},
87162306a36Sopenharmony_ci	[ADIS16505_1] = {
87262306a36Sopenharmony_ci		.name = "adis16505-1",
87362306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(adis16475_channels),
87462306a36Sopenharmony_ci		.channels = adis16475_channels,
87562306a36Sopenharmony_ci		.gyro_max_val = 1,
87662306a36Sopenharmony_ci		.gyro_max_scale = IIO_RAD_TO_DEGREE(160 << 16),
87762306a36Sopenharmony_ci		.accel_max_val = 78,
87862306a36Sopenharmony_ci		.accel_max_scale = 32000 << 16,
87962306a36Sopenharmony_ci		.temp_scale = 100,
88062306a36Sopenharmony_ci		.int_clk = 2000,
88162306a36Sopenharmony_ci		.max_dec = 1999,
88262306a36Sopenharmony_ci		.sync = adis16475_sync_mode,
88362306a36Sopenharmony_ci		/* pulse sync not supported */
88462306a36Sopenharmony_ci		.num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1,
88562306a36Sopenharmony_ci		.has_burst32 = true,
88662306a36Sopenharmony_ci		.adis_data = ADIS16475_DATA(16505, &adis1650x_timeouts),
88762306a36Sopenharmony_ci	},
88862306a36Sopenharmony_ci	[ADIS16505_2] = {
88962306a36Sopenharmony_ci		.name = "adis16505-2",
89062306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(adis16475_channels),
89162306a36Sopenharmony_ci		.channels = adis16475_channels,
89262306a36Sopenharmony_ci		.gyro_max_val = 1,
89362306a36Sopenharmony_ci		.gyro_max_scale = IIO_RAD_TO_DEGREE(40 << 16),
89462306a36Sopenharmony_ci		.accel_max_val = 78,
89562306a36Sopenharmony_ci		.accel_max_scale = 32000 << 16,
89662306a36Sopenharmony_ci		.temp_scale = 100,
89762306a36Sopenharmony_ci		.int_clk = 2000,
89862306a36Sopenharmony_ci		.max_dec = 1999,
89962306a36Sopenharmony_ci		.sync = adis16475_sync_mode,
90062306a36Sopenharmony_ci		/* pulse sync not supported */
90162306a36Sopenharmony_ci		.num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1,
90262306a36Sopenharmony_ci		.has_burst32 = true,
90362306a36Sopenharmony_ci		.adis_data = ADIS16475_DATA(16505, &adis1650x_timeouts),
90462306a36Sopenharmony_ci	},
90562306a36Sopenharmony_ci	[ADIS16505_3] = {
90662306a36Sopenharmony_ci		.name = "adis16505-3",
90762306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(adis16475_channels),
90862306a36Sopenharmony_ci		.channels = adis16475_channels,
90962306a36Sopenharmony_ci		.gyro_max_val = 1,
91062306a36Sopenharmony_ci		.gyro_max_scale = IIO_RAD_TO_DEGREE(10 << 16),
91162306a36Sopenharmony_ci		.accel_max_val = 78,
91262306a36Sopenharmony_ci		.accel_max_scale = 32000 << 16,
91362306a36Sopenharmony_ci		.temp_scale = 100,
91462306a36Sopenharmony_ci		.int_clk = 2000,
91562306a36Sopenharmony_ci		.max_dec = 1999,
91662306a36Sopenharmony_ci		.sync = adis16475_sync_mode,
91762306a36Sopenharmony_ci		/* pulse sync not supported */
91862306a36Sopenharmony_ci		.num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1,
91962306a36Sopenharmony_ci		.has_burst32 = true,
92062306a36Sopenharmony_ci		.adis_data = ADIS16475_DATA(16505, &adis1650x_timeouts),
92162306a36Sopenharmony_ci	},
92262306a36Sopenharmony_ci	[ADIS16507_1] = {
92362306a36Sopenharmony_ci		.name = "adis16507-1",
92462306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(adis16475_channels),
92562306a36Sopenharmony_ci		.channels = adis16475_channels,
92662306a36Sopenharmony_ci		.gyro_max_val = 1,
92762306a36Sopenharmony_ci		.gyro_max_scale = IIO_RAD_TO_DEGREE(160 << 16),
92862306a36Sopenharmony_ci		.accel_max_val = 392,
92962306a36Sopenharmony_ci		.accel_max_scale = 32000 << 16,
93062306a36Sopenharmony_ci		.temp_scale = 100,
93162306a36Sopenharmony_ci		.int_clk = 2000,
93262306a36Sopenharmony_ci		.max_dec = 1999,
93362306a36Sopenharmony_ci		.sync = adis16475_sync_mode,
93462306a36Sopenharmony_ci		/* pulse sync not supported */
93562306a36Sopenharmony_ci		.num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1,
93662306a36Sopenharmony_ci		.has_burst32 = true,
93762306a36Sopenharmony_ci		.adis_data = ADIS16475_DATA(16507, &adis1650x_timeouts),
93862306a36Sopenharmony_ci	},
93962306a36Sopenharmony_ci	[ADIS16507_2] = {
94062306a36Sopenharmony_ci		.name = "adis16507-2",
94162306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(adis16475_channels),
94262306a36Sopenharmony_ci		.channels = adis16475_channels,
94362306a36Sopenharmony_ci		.gyro_max_val = 1,
94462306a36Sopenharmony_ci		.gyro_max_scale = IIO_RAD_TO_DEGREE(40 << 16),
94562306a36Sopenharmony_ci		.accel_max_val = 392,
94662306a36Sopenharmony_ci		.accel_max_scale = 32000 << 16,
94762306a36Sopenharmony_ci		.temp_scale = 100,
94862306a36Sopenharmony_ci		.int_clk = 2000,
94962306a36Sopenharmony_ci		.max_dec = 1999,
95062306a36Sopenharmony_ci		.sync = adis16475_sync_mode,
95162306a36Sopenharmony_ci		/* pulse sync not supported */
95262306a36Sopenharmony_ci		.num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1,
95362306a36Sopenharmony_ci		.has_burst32 = true,
95462306a36Sopenharmony_ci		.adis_data = ADIS16475_DATA(16507, &adis1650x_timeouts),
95562306a36Sopenharmony_ci	},
95662306a36Sopenharmony_ci	[ADIS16507_3] = {
95762306a36Sopenharmony_ci		.name = "adis16507-3",
95862306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(adis16475_channels),
95962306a36Sopenharmony_ci		.channels = adis16475_channels,
96062306a36Sopenharmony_ci		.gyro_max_val = 1,
96162306a36Sopenharmony_ci		.gyro_max_scale = IIO_RAD_TO_DEGREE(10 << 16),
96262306a36Sopenharmony_ci		.accel_max_val = 392,
96362306a36Sopenharmony_ci		.accel_max_scale = 32000 << 16,
96462306a36Sopenharmony_ci		.temp_scale = 100,
96562306a36Sopenharmony_ci		.int_clk = 2000,
96662306a36Sopenharmony_ci		.max_dec = 1999,
96762306a36Sopenharmony_ci		.sync = adis16475_sync_mode,
96862306a36Sopenharmony_ci		/* pulse sync not supported */
96962306a36Sopenharmony_ci		.num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1,
97062306a36Sopenharmony_ci		.has_burst32 = true,
97162306a36Sopenharmony_ci		.adis_data = ADIS16475_DATA(16507, &adis1650x_timeouts),
97262306a36Sopenharmony_ci	},
97362306a36Sopenharmony_ci};
97462306a36Sopenharmony_ci
97562306a36Sopenharmony_cistatic const struct iio_info adis16475_info = {
97662306a36Sopenharmony_ci	.read_raw = &adis16475_read_raw,
97762306a36Sopenharmony_ci	.write_raw = &adis16475_write_raw,
97862306a36Sopenharmony_ci	.update_scan_mode = adis_update_scan_mode,
97962306a36Sopenharmony_ci	.debugfs_reg_access = adis_debugfs_reg_access,
98062306a36Sopenharmony_ci};
98162306a36Sopenharmony_ci
98262306a36Sopenharmony_cistatic bool adis16475_validate_crc(const u8 *buffer, u16 crc,
98362306a36Sopenharmony_ci				   const bool burst32)
98462306a36Sopenharmony_ci{
98562306a36Sopenharmony_ci	int i;
98662306a36Sopenharmony_ci	/* extra 6 elements for low gyro and accel */
98762306a36Sopenharmony_ci	const u16 sz = burst32 ? ADIS16475_BURST32_MAX_DATA :
98862306a36Sopenharmony_ci		ADIS16475_BURST_MAX_DATA;
98962306a36Sopenharmony_ci
99062306a36Sopenharmony_ci	for (i = 0; i < sz - 2; i++)
99162306a36Sopenharmony_ci		crc -= buffer[i];
99262306a36Sopenharmony_ci
99362306a36Sopenharmony_ci	return crc == 0;
99462306a36Sopenharmony_ci}
99562306a36Sopenharmony_ci
99662306a36Sopenharmony_cistatic void adis16475_burst32_check(struct adis16475 *st)
99762306a36Sopenharmony_ci{
99862306a36Sopenharmony_ci	int ret;
99962306a36Sopenharmony_ci	struct adis *adis = &st->adis;
100062306a36Sopenharmony_ci
100162306a36Sopenharmony_ci	if (!st->info->has_burst32)
100262306a36Sopenharmony_ci		return;
100362306a36Sopenharmony_ci
100462306a36Sopenharmony_ci	if (st->lsb_flag && !st->burst32) {
100562306a36Sopenharmony_ci		const u16 en = ADIS16500_BURST32(1);
100662306a36Sopenharmony_ci
100762306a36Sopenharmony_ci		ret = __adis_update_bits(&st->adis, ADIS16475_REG_MSG_CTRL,
100862306a36Sopenharmony_ci					 ADIS16500_BURST32_MASK, en);
100962306a36Sopenharmony_ci		if (ret)
101062306a36Sopenharmony_ci			return;
101162306a36Sopenharmony_ci
101262306a36Sopenharmony_ci		st->burst32 = true;
101362306a36Sopenharmony_ci
101462306a36Sopenharmony_ci		/*
101562306a36Sopenharmony_ci		 * In 32-bit mode we need extra 2 bytes for all gyro
101662306a36Sopenharmony_ci		 * and accel channels.
101762306a36Sopenharmony_ci		 */
101862306a36Sopenharmony_ci		adis->burst_extra_len = 6 * sizeof(u16);
101962306a36Sopenharmony_ci		adis->xfer[1].len += 6 * sizeof(u16);
102062306a36Sopenharmony_ci		dev_dbg(&adis->spi->dev, "Enable burst32 mode, xfer:%d",
102162306a36Sopenharmony_ci			adis->xfer[1].len);
102262306a36Sopenharmony_ci
102362306a36Sopenharmony_ci	} else if (!st->lsb_flag && st->burst32) {
102462306a36Sopenharmony_ci		const u16 en = ADIS16500_BURST32(0);
102562306a36Sopenharmony_ci
102662306a36Sopenharmony_ci		ret = __adis_update_bits(&st->adis, ADIS16475_REG_MSG_CTRL,
102762306a36Sopenharmony_ci					 ADIS16500_BURST32_MASK, en);
102862306a36Sopenharmony_ci		if (ret)
102962306a36Sopenharmony_ci			return;
103062306a36Sopenharmony_ci
103162306a36Sopenharmony_ci		st->burst32 = false;
103262306a36Sopenharmony_ci
103362306a36Sopenharmony_ci		/* Remove the extra bits */
103462306a36Sopenharmony_ci		adis->burst_extra_len = 0;
103562306a36Sopenharmony_ci		adis->xfer[1].len -= 6 * sizeof(u16);
103662306a36Sopenharmony_ci		dev_dbg(&adis->spi->dev, "Disable burst32 mode, xfer:%d\n",
103762306a36Sopenharmony_ci			adis->xfer[1].len);
103862306a36Sopenharmony_ci	}
103962306a36Sopenharmony_ci}
104062306a36Sopenharmony_ci
104162306a36Sopenharmony_cistatic irqreturn_t adis16475_trigger_handler(int irq, void *p)
104262306a36Sopenharmony_ci{
104362306a36Sopenharmony_ci	struct iio_poll_func *pf = p;
104462306a36Sopenharmony_ci	struct iio_dev *indio_dev = pf->indio_dev;
104562306a36Sopenharmony_ci	struct adis16475 *st = iio_priv(indio_dev);
104662306a36Sopenharmony_ci	struct adis *adis = &st->adis;
104762306a36Sopenharmony_ci	int ret, bit, i = 0;
104862306a36Sopenharmony_ci	__be16 *buffer;
104962306a36Sopenharmony_ci	u16 crc;
105062306a36Sopenharmony_ci	bool valid;
105162306a36Sopenharmony_ci	/* offset until the first element after gyro and accel */
105262306a36Sopenharmony_ci	const u8 offset = st->burst32 ? 13 : 7;
105362306a36Sopenharmony_ci
105462306a36Sopenharmony_ci	ret = spi_sync(adis->spi, &adis->msg);
105562306a36Sopenharmony_ci	if (ret)
105662306a36Sopenharmony_ci		goto check_burst32;
105762306a36Sopenharmony_ci
105862306a36Sopenharmony_ci	buffer = adis->buffer;
105962306a36Sopenharmony_ci
106062306a36Sopenharmony_ci	crc = be16_to_cpu(buffer[offset + 2]);
106162306a36Sopenharmony_ci	valid = adis16475_validate_crc(adis->buffer, crc, st->burst32);
106262306a36Sopenharmony_ci	if (!valid) {
106362306a36Sopenharmony_ci		dev_err(&adis->spi->dev, "Invalid crc\n");
106462306a36Sopenharmony_ci		goto check_burst32;
106562306a36Sopenharmony_ci	}
106662306a36Sopenharmony_ci
106762306a36Sopenharmony_ci	for_each_set_bit(bit, indio_dev->active_scan_mask,
106862306a36Sopenharmony_ci			 indio_dev->masklength) {
106962306a36Sopenharmony_ci		/*
107062306a36Sopenharmony_ci		 * When burst mode is used, system flags is the first data
107162306a36Sopenharmony_ci		 * channel in the sequence, but the scan index is 7.
107262306a36Sopenharmony_ci		 */
107362306a36Sopenharmony_ci		switch (bit) {
107462306a36Sopenharmony_ci		case ADIS16475_SCAN_TEMP:
107562306a36Sopenharmony_ci			st->data[i++] = buffer[offset];
107662306a36Sopenharmony_ci			break;
107762306a36Sopenharmony_ci		case ADIS16475_SCAN_GYRO_X ... ADIS16475_SCAN_ACCEL_Z:
107862306a36Sopenharmony_ci			/*
107962306a36Sopenharmony_ci			 * The first 2 bytes on the received data are the
108062306a36Sopenharmony_ci			 * DIAG_STAT reg, hence the +1 offset here...
108162306a36Sopenharmony_ci			 */
108262306a36Sopenharmony_ci			if (st->burst32) {
108362306a36Sopenharmony_ci				/* upper 16 */
108462306a36Sopenharmony_ci				st->data[i++] = buffer[bit * 2 + 2];
108562306a36Sopenharmony_ci				/* lower 16 */
108662306a36Sopenharmony_ci				st->data[i++] = buffer[bit * 2 + 1];
108762306a36Sopenharmony_ci			} else {
108862306a36Sopenharmony_ci				st->data[i++] = buffer[bit + 1];
108962306a36Sopenharmony_ci				/*
109062306a36Sopenharmony_ci				 * Don't bother in doing the manual read if the
109162306a36Sopenharmony_ci				 * device supports burst32. burst32 will be
109262306a36Sopenharmony_ci				 * enabled in the next call to
109362306a36Sopenharmony_ci				 * adis16475_burst32_check()...
109462306a36Sopenharmony_ci				 */
109562306a36Sopenharmony_ci				if (st->lsb_flag && !st->info->has_burst32) {
109662306a36Sopenharmony_ci					u16 val = 0;
109762306a36Sopenharmony_ci					const u32 reg = ADIS16475_REG_X_GYRO_L +
109862306a36Sopenharmony_ci						bit * 4;
109962306a36Sopenharmony_ci
110062306a36Sopenharmony_ci					adis_read_reg_16(adis, reg, &val);
110162306a36Sopenharmony_ci					st->data[i++] = cpu_to_be16(val);
110262306a36Sopenharmony_ci				} else {
110362306a36Sopenharmony_ci					/* lower not used */
110462306a36Sopenharmony_ci					st->data[i++] = 0;
110562306a36Sopenharmony_ci				}
110662306a36Sopenharmony_ci			}
110762306a36Sopenharmony_ci			break;
110862306a36Sopenharmony_ci		}
110962306a36Sopenharmony_ci	}
111062306a36Sopenharmony_ci
111162306a36Sopenharmony_ci	iio_push_to_buffers_with_timestamp(indio_dev, st->data, pf->timestamp);
111262306a36Sopenharmony_cicheck_burst32:
111362306a36Sopenharmony_ci	/*
111462306a36Sopenharmony_ci	 * We only check the burst mode at the end of the current capture since
111562306a36Sopenharmony_ci	 * it takes a full data ready cycle for the device to update the burst
111662306a36Sopenharmony_ci	 * array.
111762306a36Sopenharmony_ci	 */
111862306a36Sopenharmony_ci	adis16475_burst32_check(st);
111962306a36Sopenharmony_ci	iio_trigger_notify_done(indio_dev->trig);
112062306a36Sopenharmony_ci
112162306a36Sopenharmony_ci	return IRQ_HANDLED;
112262306a36Sopenharmony_ci}
112362306a36Sopenharmony_ci
112462306a36Sopenharmony_cistatic int adis16475_config_sync_mode(struct adis16475 *st)
112562306a36Sopenharmony_ci{
112662306a36Sopenharmony_ci	int ret;
112762306a36Sopenharmony_ci	struct device *dev = &st->adis.spi->dev;
112862306a36Sopenharmony_ci	const struct adis16475_sync *sync;
112962306a36Sopenharmony_ci	u32 sync_mode;
113062306a36Sopenharmony_ci
113162306a36Sopenharmony_ci	/* default to internal clk */
113262306a36Sopenharmony_ci	st->clk_freq = st->info->int_clk * 1000;
113362306a36Sopenharmony_ci
113462306a36Sopenharmony_ci	ret = device_property_read_u32(dev, "adi,sync-mode", &sync_mode);
113562306a36Sopenharmony_ci	if (ret)
113662306a36Sopenharmony_ci		return 0;
113762306a36Sopenharmony_ci
113862306a36Sopenharmony_ci	if (sync_mode >= st->info->num_sync) {
113962306a36Sopenharmony_ci		dev_err(dev, "Invalid sync mode: %u for %s\n", sync_mode,
114062306a36Sopenharmony_ci			st->info->name);
114162306a36Sopenharmony_ci		return -EINVAL;
114262306a36Sopenharmony_ci	}
114362306a36Sopenharmony_ci
114462306a36Sopenharmony_ci	sync = &st->info->sync[sync_mode];
114562306a36Sopenharmony_ci	st->sync_mode = sync->sync_mode;
114662306a36Sopenharmony_ci
114762306a36Sopenharmony_ci	/* All the other modes require external input signal */
114862306a36Sopenharmony_ci	if (sync->sync_mode != ADIS16475_SYNC_OUTPUT) {
114962306a36Sopenharmony_ci		struct clk *clk = devm_clk_get_enabled(dev, NULL);
115062306a36Sopenharmony_ci
115162306a36Sopenharmony_ci		if (IS_ERR(clk))
115262306a36Sopenharmony_ci			return PTR_ERR(clk);
115362306a36Sopenharmony_ci
115462306a36Sopenharmony_ci		st->clk_freq = clk_get_rate(clk);
115562306a36Sopenharmony_ci		if (st->clk_freq < sync->min_rate ||
115662306a36Sopenharmony_ci		    st->clk_freq > sync->max_rate) {
115762306a36Sopenharmony_ci			dev_err(dev,
115862306a36Sopenharmony_ci				"Clk rate:%u not in a valid range:[%u %u]\n",
115962306a36Sopenharmony_ci				st->clk_freq, sync->min_rate, sync->max_rate);
116062306a36Sopenharmony_ci			return -EINVAL;
116162306a36Sopenharmony_ci		}
116262306a36Sopenharmony_ci
116362306a36Sopenharmony_ci		if (sync->sync_mode == ADIS16475_SYNC_SCALED) {
116462306a36Sopenharmony_ci			u16 up_scale;
116562306a36Sopenharmony_ci
116662306a36Sopenharmony_ci			/*
116762306a36Sopenharmony_ci			 * In sync scaled mode, the IMU sample rate is the clk_freq * sync_scale.
116862306a36Sopenharmony_ci			 * Hence, default the IMU sample rate to the highest multiple of the input
116962306a36Sopenharmony_ci			 * clock lower than the IMU max sample rate. The optimal range is
117062306a36Sopenharmony_ci			 * 1900-2100 sps...
117162306a36Sopenharmony_ci			 */
117262306a36Sopenharmony_ci			up_scale = 2100 / st->clk_freq;
117362306a36Sopenharmony_ci
117462306a36Sopenharmony_ci			ret = __adis_write_reg_16(&st->adis,
117562306a36Sopenharmony_ci						  ADIS16475_REG_UP_SCALE,
117662306a36Sopenharmony_ci						  up_scale);
117762306a36Sopenharmony_ci			if (ret)
117862306a36Sopenharmony_ci				return ret;
117962306a36Sopenharmony_ci		}
118062306a36Sopenharmony_ci
118162306a36Sopenharmony_ci		st->clk_freq *= 1000;
118262306a36Sopenharmony_ci	}
118362306a36Sopenharmony_ci	/*
118462306a36Sopenharmony_ci	 * Keep in mind that the mask for the clk modes in adis1650*
118562306a36Sopenharmony_ci	 * chips is different (1100 instead of 11100). However, we
118662306a36Sopenharmony_ci	 * are not configuring BIT(4) in these chips and the default
118762306a36Sopenharmony_ci	 * value is 0, so we are fine in doing the below operations.
118862306a36Sopenharmony_ci	 * I'm keeping this for simplicity and avoiding extra variables
118962306a36Sopenharmony_ci	 * in chip_info.
119062306a36Sopenharmony_ci	 */
119162306a36Sopenharmony_ci	ret = __adis_update_bits(&st->adis, ADIS16475_REG_MSG_CTRL,
119262306a36Sopenharmony_ci				 ADIS16475_SYNC_MODE_MASK, sync->sync_mode);
119362306a36Sopenharmony_ci	if (ret)
119462306a36Sopenharmony_ci		return ret;
119562306a36Sopenharmony_ci
119662306a36Sopenharmony_ci	usleep_range(250, 260);
119762306a36Sopenharmony_ci
119862306a36Sopenharmony_ci	return 0;
119962306a36Sopenharmony_ci}
120062306a36Sopenharmony_ci
120162306a36Sopenharmony_cistatic int adis16475_config_irq_pin(struct adis16475 *st)
120262306a36Sopenharmony_ci{
120362306a36Sopenharmony_ci	int ret;
120462306a36Sopenharmony_ci	struct irq_data *desc;
120562306a36Sopenharmony_ci	u32 irq_type;
120662306a36Sopenharmony_ci	u16 val = 0;
120762306a36Sopenharmony_ci	u8 polarity;
120862306a36Sopenharmony_ci	struct spi_device *spi = st->adis.spi;
120962306a36Sopenharmony_ci
121062306a36Sopenharmony_ci	desc = irq_get_irq_data(spi->irq);
121162306a36Sopenharmony_ci	if (!desc) {
121262306a36Sopenharmony_ci		dev_err(&spi->dev, "Could not find IRQ %d\n", spi->irq);
121362306a36Sopenharmony_ci		return -EINVAL;
121462306a36Sopenharmony_ci	}
121562306a36Sopenharmony_ci	/*
121662306a36Sopenharmony_ci	 * It is possible to configure the data ready polarity. Furthermore, we
121762306a36Sopenharmony_ci	 * need to update the adis struct if we want data ready as active low.
121862306a36Sopenharmony_ci	 */
121962306a36Sopenharmony_ci	irq_type = irqd_get_trigger_type(desc);
122062306a36Sopenharmony_ci	if (irq_type == IRQ_TYPE_EDGE_RISING) {
122162306a36Sopenharmony_ci		polarity = 1;
122262306a36Sopenharmony_ci		st->adis.irq_flag = IRQF_TRIGGER_RISING;
122362306a36Sopenharmony_ci	} else if (irq_type == IRQ_TYPE_EDGE_FALLING) {
122462306a36Sopenharmony_ci		polarity = 0;
122562306a36Sopenharmony_ci		st->adis.irq_flag = IRQF_TRIGGER_FALLING;
122662306a36Sopenharmony_ci	} else {
122762306a36Sopenharmony_ci		dev_err(&spi->dev, "Invalid interrupt type 0x%x specified\n",
122862306a36Sopenharmony_ci			irq_type);
122962306a36Sopenharmony_ci		return -EINVAL;
123062306a36Sopenharmony_ci	}
123162306a36Sopenharmony_ci
123262306a36Sopenharmony_ci	val = ADIS16475_MSG_CTRL_DR_POL(polarity);
123362306a36Sopenharmony_ci	ret = __adis_update_bits(&st->adis, ADIS16475_REG_MSG_CTRL,
123462306a36Sopenharmony_ci				 ADIS16475_MSG_CTRL_DR_POL_MASK, val);
123562306a36Sopenharmony_ci	if (ret)
123662306a36Sopenharmony_ci		return ret;
123762306a36Sopenharmony_ci	/*
123862306a36Sopenharmony_ci	 * There is a delay writing to any bits written to the MSC_CTRL
123962306a36Sopenharmony_ci	 * register. It should not be bigger than 200us, so 250 should be more
124062306a36Sopenharmony_ci	 * than enough!
124162306a36Sopenharmony_ci	 */
124262306a36Sopenharmony_ci	usleep_range(250, 260);
124362306a36Sopenharmony_ci
124462306a36Sopenharmony_ci	return 0;
124562306a36Sopenharmony_ci}
124662306a36Sopenharmony_ci
124762306a36Sopenharmony_ci
124862306a36Sopenharmony_cistatic int adis16475_probe(struct spi_device *spi)
124962306a36Sopenharmony_ci{
125062306a36Sopenharmony_ci	struct iio_dev *indio_dev;
125162306a36Sopenharmony_ci	struct adis16475 *st;
125262306a36Sopenharmony_ci	int ret;
125362306a36Sopenharmony_ci
125462306a36Sopenharmony_ci	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
125562306a36Sopenharmony_ci	if (!indio_dev)
125662306a36Sopenharmony_ci		return -ENOMEM;
125762306a36Sopenharmony_ci
125862306a36Sopenharmony_ci	st = iio_priv(indio_dev);
125962306a36Sopenharmony_ci
126062306a36Sopenharmony_ci	st->info = spi_get_device_match_data(spi);
126162306a36Sopenharmony_ci	if (!st->info)
126262306a36Sopenharmony_ci		return -EINVAL;
126362306a36Sopenharmony_ci
126462306a36Sopenharmony_ci	ret = adis_init(&st->adis, indio_dev, spi, &st->info->adis_data);
126562306a36Sopenharmony_ci	if (ret)
126662306a36Sopenharmony_ci		return ret;
126762306a36Sopenharmony_ci
126862306a36Sopenharmony_ci	indio_dev->name = st->info->name;
126962306a36Sopenharmony_ci	indio_dev->channels = st->info->channels;
127062306a36Sopenharmony_ci	indio_dev->num_channels = st->info->num_channels;
127162306a36Sopenharmony_ci	indio_dev->info = &adis16475_info;
127262306a36Sopenharmony_ci	indio_dev->modes = INDIO_DIRECT_MODE;
127362306a36Sopenharmony_ci
127462306a36Sopenharmony_ci	ret = __adis_initial_startup(&st->adis);
127562306a36Sopenharmony_ci	if (ret)
127662306a36Sopenharmony_ci		return ret;
127762306a36Sopenharmony_ci
127862306a36Sopenharmony_ci	ret = adis16475_config_irq_pin(st);
127962306a36Sopenharmony_ci	if (ret)
128062306a36Sopenharmony_ci		return ret;
128162306a36Sopenharmony_ci
128262306a36Sopenharmony_ci	ret = adis16475_config_sync_mode(st);
128362306a36Sopenharmony_ci	if (ret)
128462306a36Sopenharmony_ci		return ret;
128562306a36Sopenharmony_ci
128662306a36Sopenharmony_ci	ret = devm_adis_setup_buffer_and_trigger(&st->adis, indio_dev,
128762306a36Sopenharmony_ci						 adis16475_trigger_handler);
128862306a36Sopenharmony_ci	if (ret)
128962306a36Sopenharmony_ci		return ret;
129062306a36Sopenharmony_ci
129162306a36Sopenharmony_ci	ret = devm_iio_device_register(&spi->dev, indio_dev);
129262306a36Sopenharmony_ci	if (ret)
129362306a36Sopenharmony_ci		return ret;
129462306a36Sopenharmony_ci
129562306a36Sopenharmony_ci	adis16475_debugfs_init(indio_dev);
129662306a36Sopenharmony_ci
129762306a36Sopenharmony_ci	return 0;
129862306a36Sopenharmony_ci}
129962306a36Sopenharmony_ci
130062306a36Sopenharmony_cistatic const struct of_device_id adis16475_of_match[] = {
130162306a36Sopenharmony_ci	{ .compatible = "adi,adis16470",
130262306a36Sopenharmony_ci		.data = &adis16475_chip_info[ADIS16470] },
130362306a36Sopenharmony_ci	{ .compatible = "adi,adis16475-1",
130462306a36Sopenharmony_ci		.data = &adis16475_chip_info[ADIS16475_1] },
130562306a36Sopenharmony_ci	{ .compatible = "adi,adis16475-2",
130662306a36Sopenharmony_ci		.data = &adis16475_chip_info[ADIS16475_2] },
130762306a36Sopenharmony_ci	{ .compatible = "adi,adis16475-3",
130862306a36Sopenharmony_ci		.data = &adis16475_chip_info[ADIS16475_3] },
130962306a36Sopenharmony_ci	{ .compatible = "adi,adis16477-1",
131062306a36Sopenharmony_ci		.data = &adis16475_chip_info[ADIS16477_1] },
131162306a36Sopenharmony_ci	{ .compatible = "adi,adis16477-2",
131262306a36Sopenharmony_ci		.data = &adis16475_chip_info[ADIS16477_2] },
131362306a36Sopenharmony_ci	{ .compatible = "adi,adis16477-3",
131462306a36Sopenharmony_ci		.data = &adis16475_chip_info[ADIS16477_3] },
131562306a36Sopenharmony_ci	{ .compatible = "adi,adis16465-1",
131662306a36Sopenharmony_ci		.data = &adis16475_chip_info[ADIS16465_1] },
131762306a36Sopenharmony_ci	{ .compatible = "adi,adis16465-2",
131862306a36Sopenharmony_ci		.data = &adis16475_chip_info[ADIS16465_2] },
131962306a36Sopenharmony_ci	{ .compatible = "adi,adis16465-3",
132062306a36Sopenharmony_ci		.data = &adis16475_chip_info[ADIS16465_3] },
132162306a36Sopenharmony_ci	{ .compatible = "adi,adis16467-1",
132262306a36Sopenharmony_ci		.data = &adis16475_chip_info[ADIS16467_1] },
132362306a36Sopenharmony_ci	{ .compatible = "adi,adis16467-2",
132462306a36Sopenharmony_ci		.data = &adis16475_chip_info[ADIS16467_2] },
132562306a36Sopenharmony_ci	{ .compatible = "adi,adis16467-3",
132662306a36Sopenharmony_ci		.data = &adis16475_chip_info[ADIS16467_3] },
132762306a36Sopenharmony_ci	{ .compatible = "adi,adis16500",
132862306a36Sopenharmony_ci		.data = &adis16475_chip_info[ADIS16500] },
132962306a36Sopenharmony_ci	{ .compatible = "adi,adis16505-1",
133062306a36Sopenharmony_ci		.data = &adis16475_chip_info[ADIS16505_1] },
133162306a36Sopenharmony_ci	{ .compatible = "adi,adis16505-2",
133262306a36Sopenharmony_ci		.data = &adis16475_chip_info[ADIS16505_2] },
133362306a36Sopenharmony_ci	{ .compatible = "adi,adis16505-3",
133462306a36Sopenharmony_ci		.data = &adis16475_chip_info[ADIS16505_3] },
133562306a36Sopenharmony_ci	{ .compatible = "adi,adis16507-1",
133662306a36Sopenharmony_ci		.data = &adis16475_chip_info[ADIS16507_1] },
133762306a36Sopenharmony_ci	{ .compatible = "adi,adis16507-2",
133862306a36Sopenharmony_ci		.data = &adis16475_chip_info[ADIS16507_2] },
133962306a36Sopenharmony_ci	{ .compatible = "adi,adis16507-3",
134062306a36Sopenharmony_ci		.data = &adis16475_chip_info[ADIS16507_3] },
134162306a36Sopenharmony_ci	{ },
134262306a36Sopenharmony_ci};
134362306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, adis16475_of_match);
134462306a36Sopenharmony_ci
134562306a36Sopenharmony_cistatic const struct spi_device_id adis16475_ids[] = {
134662306a36Sopenharmony_ci	{ "adis16470", (kernel_ulong_t)&adis16475_chip_info[ADIS16470] },
134762306a36Sopenharmony_ci	{ "adis16475-1", (kernel_ulong_t)&adis16475_chip_info[ADIS16475_1] },
134862306a36Sopenharmony_ci	{ "adis16475-2", (kernel_ulong_t)&adis16475_chip_info[ADIS16475_2] },
134962306a36Sopenharmony_ci	{ "adis16475-3", (kernel_ulong_t)&adis16475_chip_info[ADIS16475_3] },
135062306a36Sopenharmony_ci	{ "adis16477-1", (kernel_ulong_t)&adis16475_chip_info[ADIS16477_1] },
135162306a36Sopenharmony_ci	{ "adis16477-2", (kernel_ulong_t)&adis16475_chip_info[ADIS16477_2] },
135262306a36Sopenharmony_ci	{ "adis16477-3", (kernel_ulong_t)&adis16475_chip_info[ADIS16477_3] },
135362306a36Sopenharmony_ci	{ "adis16465-1", (kernel_ulong_t)&adis16475_chip_info[ADIS16465_1] },
135462306a36Sopenharmony_ci	{ "adis16465-2", (kernel_ulong_t)&adis16475_chip_info[ADIS16465_2] },
135562306a36Sopenharmony_ci	{ "adis16465-3", (kernel_ulong_t)&adis16475_chip_info[ADIS16465_3] },
135662306a36Sopenharmony_ci	{ "adis16467-1", (kernel_ulong_t)&adis16475_chip_info[ADIS16467_1] },
135762306a36Sopenharmony_ci	{ "adis16467-2", (kernel_ulong_t)&adis16475_chip_info[ADIS16467_2] },
135862306a36Sopenharmony_ci	{ "adis16467-3", (kernel_ulong_t)&adis16475_chip_info[ADIS16467_3] },
135962306a36Sopenharmony_ci	{ "adis16500", (kernel_ulong_t)&adis16475_chip_info[ADIS16500] },
136062306a36Sopenharmony_ci	{ "adis16505-1", (kernel_ulong_t)&adis16475_chip_info[ADIS16505_1] },
136162306a36Sopenharmony_ci	{ "adis16505-2", (kernel_ulong_t)&adis16475_chip_info[ADIS16505_2] },
136262306a36Sopenharmony_ci	{ "adis16505-3", (kernel_ulong_t)&adis16475_chip_info[ADIS16505_3] },
136362306a36Sopenharmony_ci	{ "adis16507-1", (kernel_ulong_t)&adis16475_chip_info[ADIS16507_1] },
136462306a36Sopenharmony_ci	{ "adis16507-2", (kernel_ulong_t)&adis16475_chip_info[ADIS16507_2] },
136562306a36Sopenharmony_ci	{ "adis16507-3", (kernel_ulong_t)&adis16475_chip_info[ADIS16507_3] },
136662306a36Sopenharmony_ci	{ }
136762306a36Sopenharmony_ci};
136862306a36Sopenharmony_ciMODULE_DEVICE_TABLE(spi, adis16475_ids);
136962306a36Sopenharmony_ci
137062306a36Sopenharmony_cistatic struct spi_driver adis16475_driver = {
137162306a36Sopenharmony_ci	.driver = {
137262306a36Sopenharmony_ci		.name = "adis16475",
137362306a36Sopenharmony_ci		.of_match_table = adis16475_of_match,
137462306a36Sopenharmony_ci	},
137562306a36Sopenharmony_ci	.probe = adis16475_probe,
137662306a36Sopenharmony_ci	.id_table = adis16475_ids,
137762306a36Sopenharmony_ci};
137862306a36Sopenharmony_cimodule_spi_driver(adis16475_driver);
137962306a36Sopenharmony_ci
138062306a36Sopenharmony_ciMODULE_AUTHOR("Nuno Sa <nuno.sa@analog.com>");
138162306a36Sopenharmony_ciMODULE_DESCRIPTION("Analog Devices ADIS16475 IMU driver");
138262306a36Sopenharmony_ciMODULE_LICENSE("GPL");
138362306a36Sopenharmony_ciMODULE_IMPORT_NS(IIO_ADISLIB);
1384