diff --git a/MAINTAINERS b/MAINTAINERS
index 8fa40c3eb72a..f11262f1f3bb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1008,6 +1008,14 @@ W:
http://ez.analog.com/community/linux-device-drivers
F: drivers/iio/imu/adis16460.c
F: Documentation/devicetree/bindings/iio/imu/adi,adis16460
.yaml
+ANALOG DEVICES INC ADIS16475 DRIVER
+M: Nuno Sa <nuno.sa@xxxxxxxxxx>
+L: linux-iio@xxxxxxxxxxxxxxx
+W: http://ez.analog.com/community/linux-device-drivers
+S: Supported
+F: drivers/iio/imu/adis16475.c
+F: Documentation/ABI/testing/sysfs-bus-iio-imu-adis16475
+
ANALOG DEVICES INC ADM1177 DRIVER
M: Beniamin Bia <beniamin.bia@xxxxxxxxxx>
M: Michael Hennerich <Michael.Hennerich@xxxxxxxxxx>
diff --git a/drivers/iio/imu/Kconfig b/drivers/iio/imu/Kconfig
index 60bb1029e759..fc4123d518bc 100644
--- a/drivers/iio/imu/Kconfig
+++ b/drivers/iio/imu/Kconfig
@@ -29,6 +29,19 @@ config ADIS16460
To compile this driver as a module, choose M here: the module
will be
called adis16460.
+config ADIS16475
+ tristate "Analog Devices ADIS16475 and similar IMU driver"
+ depends on SPI
+ select IIO_ADIS_LIB
+ select IIO_ADIS_LIB_BUFFER if IIO_BUFFER
+ help
+ Say yes here to build support for Analog Devices ADIS16470,
ADIS16475,
+ ADIS16477, ADIS16465, ADIS16467, ADIS16500, ADIS16505,
ADIS16507 inertial
+ sensors.
+
+ To compile this driver as a module, choose M here: the module
will be
+ called adis16475.
+
config ADIS16480
tristate "Analog Devices ADIS16480 and similar IMU driver"
depends on SPI
diff --git a/drivers/iio/imu/Makefile b/drivers/iio/imu/Makefile
index 5237fd4bc384..88b2c4555230 100644
--- a/drivers/iio/imu/Makefile
+++ b/drivers/iio/imu/Makefile
@@ -6,6 +6,7 @@
# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_ADIS16400) += adis16400.o
obj-$(CONFIG_ADIS16460) += adis16460.o
+obj-$(CONFIG_ADIS16475) += adis16475.o
obj-$(CONFIG_ADIS16480) += adis16480.o
adis_lib-y += adis.o
diff --git a/drivers/iio/imu/adis16475.c
b/drivers/iio/imu/adis16475.c
new file mode 100644
index 000000000000..f7c637734ec8
--- /dev/null
+++ b/drivers/iio/imu/adis16475.c
@@ -0,0 +1,1304 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ADIS16475 IMU driver
+ *
+ * Copyright 2019 Analog Devices Inc.
+ */
+#include <asm/unaligned.h>
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/imu/adis.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/spi/spi.h>
+
+#define ADIS16475_REG_DIAG_STAT 0x02
+#define ADIS16475_REG_X_GYRO_L 0x04
+#define ADIS16475_REG_Y_GYRO_L 0x08
+#define ADIS16475_REG_Z_GYRO_L 0x0C
+#define ADIS16475_REG_X_ACCEL_L 0x10
+#define ADIS16475_REG_Y_ACCEL_L 0x14
+#define ADIS16475_REG_Z_ACCEL_L 0x18
+#define ADIS16475_REG_TEMP_OUT 0x1c
+#define ADIS16475_REG_X_GYRO_BIAS_L 0x40
+#define ADIS16475_REG_Y_GYRO_BIAS_L 0x44
+#define ADIS16475_REG_Z_GYRO_BIAS_L 0x48
+#define ADIS16475_REG_X_ACCEL_BIAS_L 0x4c
+#define ADIS16475_REG_Y_ACCEL_BIAS_L 0x50
+#define ADIS16475_REG_Z_ACCEL_BIAS_L 0x54
+#define ADIS16475_REG_FILT_CTRL 0x5c
+#define ADIS16475_FILT_CTRL_MASK GENMASK(2, 0)
+#define ADIS16475_FILT_CTRL(x) FIELD_PREP(ADIS16475_FI
LT_CTRL_MASK, x)
+#define ADIS16475_REG_MSG_CTRL 0x60
+#define ADIS16475_MSG_CTRL_DR_POL_MASK BIT(0)
+#define ADIS16475_MSG_CTRL_DR_POL(x) \
+ FIELD_PREP(ADIS16475_MSG_CTRL_DR_POL_MA
SK, x)
+#define ADIS16475_EXT_CLK_MASK GENMASK(4, 2)
+#define ADIS16475_EXT_CLK(x) FIELD_PREP(ADIS16475_EX
T_CLK_MASK, x)
+#define ADIS16475_REG_UP_SCALE 0x62
+#define ADIS16475_REG_DEC_RATE 0x64
+#define ADIS16475_REG_GLOB_CMD 0x68
+#define ADIS16475_REG_FIRM_REV 0x6c
+#define ADIS16475_REG_FIRM_DM 0x6e
+#define ADIS16475_REG_FIRM_Y 0x70
+#define ADIS16475_REG_PROD_ID 0x72
+#define ADIS16475_REG_SERIAL_NUM 0x74
+#define ADIS16475_REG_FLASH_CNT 0x7c
+#define ADIS16500_BURST32_MASK BIT(9)
+#define ADIS16500_BURST32(x) FIELD_PREP(ADIS16500_BU
RST32_MASK, x)
+/* number of data elements in burst mode */
+#define ADIS16475_BURST_MAX_DATA 10
+#define ADIS16475_MAX_SCAN_DATA 15
+
+enum clk_mode {
+ ADIS16475_CLK_DIRECT = 1,
+ ADIS16475_CLK_SCALED,
+ ADIS16475_CLK_OUTPUT,
+ ADIS16475_CLK_PULSE = 5,
+};
+
+struct adis16475_clks {
+ const char *name;
+ enum clk_mode clk_mode;
+ u16 min_rate;
+ u16 max_rate;
+};
+
+struct adis16475_chip_info {
+ const struct iio_chan_spec *channels;
+ const struct adis16475_clks *clks;
+ const struct adis_data adis_data;
+ u32 num_channels;
+ u32 gyro_max_val;
+ u32 gyro_max_scale;
+ u32 accel_max_val;
+ u32 accel_max_scale;
+ u32 temp_scale;
+ u32 int_clk;
+ u16 max_dec;
+ u8 num_clks;
+ bool has_burst32;
+};
+
+struct adis16475 {
+ const struct adis16475_chip_info *info;
+ struct adis adis;
+ u32 clk_freq;
+ u32 cached_spi_speed_hz;
+ bool burst32;
+};
+
+enum {
+ ADIS16475_SCAN_GYRO_X,
+ ADIS16475_SCAN_GYRO_Y,
+ ADIS16475_SCAN_GYRO_Z,
+ ADIS16475_SCAN_ACCEL_X,
+ ADIS16475_SCAN_ACCEL_Y,
+ ADIS16475_SCAN_ACCEL_Z,
+ ADIS16475_SCAN_TEMP,
+ ADIS16475_SCAN_DIAG_S_FLAGS,
+ ADIS16475_SCAN_CRC_FAILURE,
+};
+
+#ifdef CONFIG_DEBUG_FS
+static ssize_t adis16475_show_firmware_revision(struct file
*file,
+ char __user *userbuf,
+ size_t count, loff_t
*ppos)
+{
+ struct adis16475 *st = file->private_data;
+ char buf[7];
+ size_t len;
+ u16 rev;
+ int ret;
+
+ ret = adis_read_reg_16(&st->adis, ADIS16475_REG_FIRM_REV,
&rev);
+ if (ret)
+ return ret;
+
+ len = scnprintf(buf, sizeof(buf), "%x.%x\n", rev >> 8, rev &
0xff);
+
+ return simple_read_from_buffer(userbuf, count, ppos, buf, len);
+}
+
+static const struct file_operations
adis16475_firmware_revision_fops = {
+ .open = simple_open,
+ .read = adis16475_show_firmware_revision,
+ .llseek = default_llseek,
+ .owner = THIS_MODULE,
+};
+
+static ssize_t adis16475_show_firmware_date(struct file *file,
+ char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct adis16475 *st = file->private_data;
+ u16 md, year;
+ char buf[12];
+ size_t len;
+ int ret;
+
+ ret = adis_read_reg_16(&st->adis, ADIS16475_REG_FIRM_Y, &year);
+ if (ret)
+ return ret;
+
+ ret = adis_read_reg_16(&st->adis, ADIS16475_REG_FIRM_DM, &md);
+ if (ret)
+ return ret;
+
+ len = snprintf(buf, sizeof(buf), "%.2x-%.2x-%.4x\n", md >> 8,
md & 0xff,
+ year);
+
+ return simple_read_from_buffer(userbuf, count, ppos, buf, len);
+}
+
+static const struct file_operations adis16475_firmware_date_fops
=
{
+ .open = simple_open,
+ .read = adis16475_show_firmware_date,
+ .llseek = default_llseek,
+ .owner = THIS_MODULE,
+};
+
+static int adis16475_show_serial_number(void *arg, u64 *val)
+{
+ struct adis16475 *st = arg;
+ u16 serial;
+ int ret;
+
+ ret = adis_read_reg_16(&st->adis, ADIS16475_REG_SERIAL_NUM,
&serial);
+ if (ret)
+ return ret;
+
+ *val = serial;
+
+ return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(adis16475_serial_number_fops,
+ adis16475_show_serial_number, NULL,
"0x%.4llx\n");
+
+static int adis16475_show_product_id(void *arg, u64 *val)
+{
+ struct adis16475 *st = arg;
+ u16 prod_id;
+ int ret;
+
+ ret = adis_read_reg_16(&st->adis, ADIS16475_REG_PROD_ID,
&prod_id);
+ if (ret)
+ return ret;
+
+ *val = prod_id;
+
+ return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(adis16475_product_id_fops,
+ adis16475_show_product_id, NULL, "%llu\n");
+
+static int adis16475_show_flash_count(void *arg, u64 *val)
+{
+ struct adis16475 *st = arg;
+ u32 flash_count;
+ int ret;
+
+ ret = adis_read_reg_32(&st->adis, ADIS16475_REG_FLASH_CNT,
+ &flash_count);
+ if (ret)
+ return ret;
+
+ *val = flash_count;
+
+ return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(adis16475_flash_count_fops,
+ adis16475_show_flash_count, NULL, "%lld\n");
+
+static int adis16475_debugfs_init(struct iio_dev *indio_dev)
+{
+ struct adis16475 *st = iio_priv(indio_dev);
+
+ debugfs_create_file("serial_number", 0400, indio_dev-
debugfs_dentry,
+ st, &adis16475_serial_number_fops);
+ debugfs_create_file("product_id", 0400, indio_dev-
debugfs_dentry, st,
+ &adis16475_product_id_fops);
+ debugfs_create_file("flash_count", 0400, indio_dev-
debugfs_dentry, st,
+ &adis16475_flash_count_fops);
+ debugfs_create_file("firmware_revision", 0400,
+ indio_dev->debugfs_dentry, st,
+ &adis16475_firmware_revision_fops);
+ debugfs_create_file("firmware_date", 0400, indio_dev-
debugfs_dentry,
+ st, &adis16475_firmware_date_fops);
+ return 0;
+}
+#else
+static int adis16475_debugfs_init(struct iio_dev *indio_dev)
+{
+ return 0;
+}
+#endif
+
+static ssize_t adis16475_burst_mode_enable_get(struct device
*dev,
+ struct device_attribute
*attr,
+ char *buf)
+{
+ struct adis16475 *st = iio_priv(dev_to_iio_dev(dev));
+
+ return sprintf(buf, "%d\n", st->adis.burst->en);
+}
+
+static ssize_t adis16475_burst_mode_enable_set(struct device
*dev,
+ struct device_attribute
*attr,
+ const char *buf, size_t
len)
+{
+ struct adis16475 *st = iio_priv(dev_to_iio_dev(dev));
+ bool val;
+ int ret;
+
+ ret = kstrtobool(buf, &val);
+ if (ret)
+ return ret;
+
+ if (val)
+ /* 1MHz max in burst mode */
+ st->adis.spi->max_speed_hz = 1000000;
+ else
+ st->adis.spi->max_speed_hz = st->cached_spi_speed_hz;
+
+ st->adis.burst->en = val;
+
+ return len;
+}
+
+static IIO_DEVICE_ATTR(burst_mode_enable, 0644,
+ adis16475_burst_mode_enable_get,
+ adis16475_burst_mode_enable_set, 0);
+
+static struct attribute *adis16475_attributes[] = {
+ &iio_dev_attr_burst_mode_enable.dev_attr.attr,