kernel: delete Linux 5.4 config and patches
[openwrt/staging/wigyori.git] / target / linux / generic / backport-5.4 / 800-v5.5-iio-imu-Add-support-for-the-FXOS8700-IMU.patch
diff --git a/target/linux/generic/backport-5.4/800-v5.5-iio-imu-Add-support-for-the-FXOS8700-IMU.patch b/target/linux/generic/backport-5.4/800-v5.5-iio-imu-Add-support-for-the-FXOS8700-IMU.patch
deleted file mode 100644 (file)
index b9cd276..0000000
+++ /dev/null
@@ -1,893 +0,0 @@
-From 84e5ddd5c46ea3bf0cad670da32028994cad5936 Mon Sep 17 00:00:00 2001
-From: Robert Jones <rjones@gateworks.com>
-Date: Mon, 14 Oct 2019 11:49:21 -0700
-Subject: [PATCH] iio: imu: Add support for the FXOS8700 IMU
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-FXOS8700CQ is a small, low-power, 3-axis linear accelerometer and 3-axis
-magnetometer combined into a single package. The device features a
-selectable I2C or point-to-point SPI serial interface with 14-bit
-accelerometer and 16-bit magnetometer ADC resolution along with
-smart-embedded functions.
-
-FXOS8700CQ has dynamically selectable accelerationfull-scale ranges of
-±2 g/±4 g/±8 g and a fixed magnetic measurement range of ±1200 μT.
-Output data rates (ODR) from 1.563 Hz to 800 Hz are selectable by the user
-for each sensor. Interleaved magnetic and acceleration data is available
-at ODR rates of up to 400 Hz. FXOS8700CQ is available in a plastic QFN
-package and it is guaranteed to operate over the extended temperature
-range of –40 °C to +85 °C.
-
-TODO: Trigger and IRQ configuration support
-
-Datasheet:
-  http://cache.freescale.com/files/sensors/doc/data_sheet/FXOS8700CQ.pdf
-
-Signed-off-by: Robert Jones <rjones@gateworks.com>
-Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
----
- drivers/iio/imu/Kconfig         |  27 ++
- drivers/iio/imu/Makefile        |   5 +
- drivers/iio/imu/fxos8700.h      |  10 +
- drivers/iio/imu/fxos8700_core.c | 649 ++++++++++++++++++++++++++++++++++++++++
- drivers/iio/imu/fxos8700_i2c.c  |  71 +++++
- drivers/iio/imu/fxos8700_spi.c  |  59 ++++
- 6 files changed, 821 insertions(+)
- create mode 100644 drivers/iio/imu/fxos8700.h
- create mode 100644 drivers/iio/imu/fxos8700_core.c
- create mode 100644 drivers/iio/imu/fxos8700_i2c.c
- create mode 100644 drivers/iio/imu/fxos8700_spi.c
-
---- a/drivers/iio/imu/Kconfig
-+++ b/drivers/iio/imu/Kconfig
-@@ -40,6 +40,33 @@ config ADIS16480
- source "drivers/iio/imu/bmi160/Kconfig"
-+config FXOS8700
-+      tristate
-+
-+config FXOS8700_I2C
-+      tristate "NXP FXOS8700 I2C driver"
-+      depends on I2C
-+      select FXOS8700
-+      select REGMAP_I2C
-+      help
-+        Say yes here to build support for the NXP FXOS8700 m+g combo
-+        sensor on I2C.
-+
-+        This driver can also be built as a module. If so, the module will be
-+        called fxos8700_i2c.
-+
-+config FXOS8700_SPI
-+      tristate "NXP FXOS8700 SPI driver"
-+      depends on SPI
-+      select FXOS8700
-+      select REGMAP_SPI
-+      help
-+        Say yes here to build support for the NXP FXOS8700 m+g combo
-+        sensor on SPI.
-+
-+        This driver can also be built as a module. If so, the module will be
-+        called fxos8700_spi.
-+
- config KMX61
-       tristate "Kionix KMX61 6-axis accelerometer and magnetometer"
-       depends on I2C
---- a/drivers/iio/imu/Makefile
-+++ b/drivers/iio/imu/Makefile
-@@ -14,6 +14,11 @@ adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) +
- obj-$(CONFIG_IIO_ADIS_LIB) += adis_lib.o
- obj-y += bmi160/
-+
-+obj-$(CONFIG_FXOS8700) += fxos8700_core.o
-+obj-$(CONFIG_FXOS8700_I2C) += fxos8700_i2c.o
-+obj-$(CONFIG_FXOS8700_SPI) += fxos8700_spi.o
-+
- obj-y += inv_mpu6050/
- obj-$(CONFIG_KMX61) += kmx61.o
---- /dev/null
-+++ b/drivers/iio/imu/fxos8700.h
-@@ -0,0 +1,10 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+#ifndef FXOS8700_H_
-+#define FXOS8700_H_
-+
-+extern const struct regmap_config fxos8700_regmap_config;
-+
-+int fxos8700_core_probe(struct device *dev, struct regmap *regmap,
-+                      const char *name, bool use_spi);
-+
-+#endif  /* FXOS8700_H_ */
---- /dev/null
-+++ b/drivers/iio/imu/fxos8700_core.c
-@@ -0,0 +1,649 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * FXOS8700 - NXP IMU (accelerometer plus magnetometer)
-+ *
-+ * IIO core driver for FXOS8700, with support for I2C/SPI busses
-+ *
-+ * TODO: Buffer, trigger, and IRQ support
-+ */
-+#include <linux/module.h>
-+#include <linux/regmap.h>
-+#include <linux/acpi.h>
-+#include <linux/bitops.h>
-+
-+#include <linux/iio/iio.h>
-+#include <linux/iio/sysfs.h>
-+
-+#include "fxos8700.h"
-+
-+/* Register Definitions */
-+#define FXOS8700_STATUS             0x00
-+#define FXOS8700_OUT_X_MSB          0x01
-+#define FXOS8700_OUT_X_LSB          0x02
-+#define FXOS8700_OUT_Y_MSB          0x03
-+#define FXOS8700_OUT_Y_LSB          0x04
-+#define FXOS8700_OUT_Z_MSB          0x05
-+#define FXOS8700_OUT_Z_LSB          0x06
-+#define FXOS8700_F_SETUP            0x09
-+#define FXOS8700_TRIG_CFG           0x0a
-+#define FXOS8700_SYSMOD             0x0b
-+#define FXOS8700_INT_SOURCE         0x0c
-+#define FXOS8700_WHO_AM_I           0x0d
-+#define FXOS8700_XYZ_DATA_CFG       0x0e
-+#define FXOS8700_HP_FILTER_CUTOFF   0x0f
-+#define FXOS8700_PL_STATUS          0x10
-+#define FXOS8700_PL_CFG             0x11
-+#define FXOS8700_PL_COUNT           0x12
-+#define FXOS8700_PL_BF_ZCOMP        0x13
-+#define FXOS8700_PL_THS_REG         0x14
-+#define FXOS8700_A_FFMT_CFG         0x15
-+#define FXOS8700_A_FFMT_SRC         0x16
-+#define FXOS8700_A_FFMT_THS         0x17
-+#define FXOS8700_A_FFMT_COUNT       0x18
-+#define FXOS8700_TRANSIENT_CFG      0x1d
-+#define FXOS8700_TRANSIENT_SRC      0x1e
-+#define FXOS8700_TRANSIENT_THS      0x1f
-+#define FXOS8700_TRANSIENT_COUNT    0x20
-+#define FXOS8700_PULSE_CFG          0x21
-+#define FXOS8700_PULSE_SRC          0x22
-+#define FXOS8700_PULSE_THSX         0x23
-+#define FXOS8700_PULSE_THSY         0x24
-+#define FXOS8700_PULSE_THSZ         0x25
-+#define FXOS8700_PULSE_TMLT         0x26
-+#define FXOS8700_PULSE_LTCY         0x27
-+#define FXOS8700_PULSE_WIND         0x28
-+#define FXOS8700_ASLP_COUNT         0x29
-+#define FXOS8700_CTRL_REG1          0x2a
-+#define FXOS8700_CTRL_REG2          0x2b
-+#define FXOS8700_CTRL_REG3          0x2c
-+#define FXOS8700_CTRL_REG4          0x2d
-+#define FXOS8700_CTRL_REG5          0x2e
-+#define FXOS8700_OFF_X              0x2f
-+#define FXOS8700_OFF_Y              0x30
-+#define FXOS8700_OFF_Z              0x31
-+#define FXOS8700_M_DR_STATUS        0x32
-+#define FXOS8700_M_OUT_X_MSB        0x33
-+#define FXOS8700_M_OUT_X_LSB        0x34
-+#define FXOS8700_M_OUT_Y_MSB        0x35
-+#define FXOS8700_M_OUT_Y_LSB        0x36
-+#define FXOS8700_M_OUT_Z_MSB        0x37
-+#define FXOS8700_M_OUT_Z_LSB        0x38
-+#define FXOS8700_CMP_X_MSB          0x39
-+#define FXOS8700_CMP_X_LSB          0x3a
-+#define FXOS8700_CMP_Y_MSB          0x3b
-+#define FXOS8700_CMP_Y_LSB          0x3c
-+#define FXOS8700_CMP_Z_MSB          0x3d
-+#define FXOS8700_CMP_Z_LSB          0x3e
-+#define FXOS8700_M_OFF_X_MSB        0x3f
-+#define FXOS8700_M_OFF_X_LSB        0x40
-+#define FXOS8700_M_OFF_Y_MSB        0x41
-+#define FXOS8700_M_OFF_Y_LSB        0x42
-+#define FXOS8700_M_OFF_Z_MSB        0x43
-+#define FXOS8700_M_OFF_Z_LSB        0x44
-+#define FXOS8700_MAX_X_MSB          0x45
-+#define FXOS8700_MAX_X_LSB          0x46
-+#define FXOS8700_MAX_Y_MSB          0x47
-+#define FXOS8700_MAX_Y_LSB          0x48
-+#define FXOS8700_MAX_Z_MSB          0x49
-+#define FXOS8700_MAX_Z_LSB          0x4a
-+#define FXOS8700_MIN_X_MSB          0x4b
-+#define FXOS8700_MIN_X_LSB          0x4c
-+#define FXOS8700_MIN_Y_MSB          0x4d
-+#define FXOS8700_MIN_Y_LSB          0x4e
-+#define FXOS8700_MIN_Z_MSB          0x4f
-+#define FXOS8700_MIN_Z_LSB          0x50
-+#define FXOS8700_TEMP               0x51
-+#define FXOS8700_M_THS_CFG          0x52
-+#define FXOS8700_M_THS_SRC          0x53
-+#define FXOS8700_M_THS_X_MSB        0x54
-+#define FXOS8700_M_THS_X_LSB        0x55
-+#define FXOS8700_M_THS_Y_MSB        0x56
-+#define FXOS8700_M_THS_Y_LSB        0x57
-+#define FXOS8700_M_THS_Z_MSB        0x58
-+#define FXOS8700_M_THS_Z_LSB        0x59
-+#define FXOS8700_M_THS_COUNT        0x5a
-+#define FXOS8700_M_CTRL_REG1        0x5b
-+#define FXOS8700_M_CTRL_REG2        0x5c
-+#define FXOS8700_M_CTRL_REG3        0x5d
-+#define FXOS8700_M_INT_SRC          0x5e
-+#define FXOS8700_A_VECM_CFG         0x5f
-+#define FXOS8700_A_VECM_THS_MSB     0x60
-+#define FXOS8700_A_VECM_THS_LSB     0x61
-+#define FXOS8700_A_VECM_CNT         0x62
-+#define FXOS8700_A_VECM_INITX_MSB   0x63
-+#define FXOS8700_A_VECM_INITX_LSB   0x64
-+#define FXOS8700_A_VECM_INITY_MSB   0x65
-+#define FXOS8700_A_VECM_INITY_LSB   0x66
-+#define FXOS8700_A_VECM_INITZ_MSB   0x67
-+#define FXOS8700_A_VECM_INITZ_LSB   0x68
-+#define FXOS8700_M_VECM_CFG         0x69
-+#define FXOS8700_M_VECM_THS_MSB     0x6a
-+#define FXOS8700_M_VECM_THS_LSB     0x6b
-+#define FXOS8700_M_VECM_CNT         0x6c
-+#define FXOS8700_M_VECM_INITX_MSB   0x6d
-+#define FXOS8700_M_VECM_INITX_LSB   0x6e
-+#define FXOS8700_M_VECM_INITY_MSB   0x6f
-+#define FXOS8700_M_VECM_INITY_LSB   0x70
-+#define FXOS8700_M_VECM_INITZ_MSB   0x71
-+#define FXOS8700_M_VECM_INITZ_LSB   0x72
-+#define FXOS8700_A_FFMT_THS_X_MSB   0x73
-+#define FXOS8700_A_FFMT_THS_X_LSB   0x74
-+#define FXOS8700_A_FFMT_THS_Y_MSB   0x75
-+#define FXOS8700_A_FFMT_THS_Y_LSB   0x76
-+#define FXOS8700_A_FFMT_THS_Z_MSB   0x77
-+#define FXOS8700_A_FFMT_THS_Z_LSB   0x78
-+#define FXOS8700_A_TRAN_INIT_MSB    0x79
-+#define FXOS8700_A_TRAN_INIT_LSB_X  0x7a
-+#define FXOS8700_A_TRAN_INIT_LSB_Y  0x7b
-+#define FXOS8700_A_TRAN_INIT_LSB_Z  0x7d
-+#define FXOS8700_TM_NVM_LOCK        0x7e
-+#define FXOS8700_NVM_DATA0_35       0x80
-+#define FXOS8700_NVM_DATA_BNK3      0xa4
-+#define FXOS8700_NVM_DATA_BNK2      0xa5
-+#define FXOS8700_NVM_DATA_BNK1      0xa6
-+#define FXOS8700_NVM_DATA_BNK0      0xa7
-+
-+/* Bit definitions for FXOS8700_CTRL_REG1 */
-+#define FXOS8700_CTRL_ODR_MSK       0x38
-+#define FXOS8700_CTRL_ODR_MAX       0x00
-+#define FXOS8700_CTRL_ODR_MIN       GENMASK(4, 3)
-+
-+/* Bit definitions for FXOS8700_M_CTRL_REG1 */
-+#define FXOS8700_HMS_MASK           GENMASK(1, 0)
-+#define FXOS8700_OS_MASK            GENMASK(4, 2)
-+
-+/* Bit definitions for FXOS8700_M_CTRL_REG2 */
-+#define FXOS8700_MAXMIN_RST         BIT(2)
-+#define FXOS8700_MAXMIN_DIS_THS     BIT(3)
-+#define FXOS8700_MAXMIN_DIS         BIT(4)
-+
-+#define FXOS8700_ACTIVE             0x01
-+#define FXOS8700_ACTIVE_MIN_USLEEP  4000 /* from table 6 in datasheet */
-+
-+#define FXOS8700_DEVICE_ID          0xC7
-+#define FXOS8700_PRE_DEVICE_ID      0xC4
-+#define FXOS8700_DATA_BUF_SIZE      3
-+
-+struct fxos8700_data {
-+      struct regmap *regmap;
-+      struct iio_trigger *trig;
-+      __be16 buf[FXOS8700_DATA_BUF_SIZE] ____cacheline_aligned;
-+};
-+
-+/* Regmap info */
-+static const struct regmap_range read_range[] = {
-+      {
-+              .range_min = FXOS8700_STATUS,
-+              .range_max = FXOS8700_A_FFMT_COUNT,
-+      }, {
-+              .range_min = FXOS8700_TRANSIENT_CFG,
-+              .range_max = FXOS8700_A_FFMT_THS_Z_LSB,
-+      },
-+};
-+
-+static const struct regmap_range write_range[] = {
-+      {
-+              .range_min = FXOS8700_F_SETUP,
-+              .range_max = FXOS8700_TRIG_CFG,
-+      }, {
-+              .range_min = FXOS8700_XYZ_DATA_CFG,
-+              .range_max = FXOS8700_HP_FILTER_CUTOFF,
-+      }, {
-+              .range_min = FXOS8700_PL_CFG,
-+              .range_max = FXOS8700_A_FFMT_CFG,
-+      }, {
-+              .range_min = FXOS8700_A_FFMT_THS,
-+              .range_max = FXOS8700_TRANSIENT_CFG,
-+      }, {
-+              .range_min = FXOS8700_TRANSIENT_THS,
-+              .range_max = FXOS8700_PULSE_CFG,
-+      }, {
-+              .range_min = FXOS8700_PULSE_THSX,
-+              .range_max = FXOS8700_OFF_Z,
-+      }, {
-+              .range_min = FXOS8700_M_OFF_X_MSB,
-+              .range_max = FXOS8700_M_OFF_Z_LSB,
-+      }, {
-+              .range_min = FXOS8700_M_THS_CFG,
-+              .range_max = FXOS8700_M_THS_CFG,
-+      }, {
-+              .range_min = FXOS8700_M_THS_X_MSB,
-+              .range_max = FXOS8700_M_CTRL_REG3,
-+      }, {
-+              .range_min = FXOS8700_A_VECM_CFG,
-+              .range_max = FXOS8700_A_FFMT_THS_Z_LSB,
-+      },
-+};
-+
-+static const struct regmap_access_table driver_read_table = {
-+      .yes_ranges =   read_range,
-+      .n_yes_ranges = ARRAY_SIZE(read_range),
-+};
-+
-+static const struct regmap_access_table driver_write_table = {
-+      .yes_ranges =   write_range,
-+      .n_yes_ranges = ARRAY_SIZE(write_range),
-+};
-+
-+const struct regmap_config fxos8700_regmap_config = {
-+      .reg_bits = 8,
-+      .val_bits = 8,
-+      .max_register = FXOS8700_NVM_DATA_BNK0,
-+      .rd_table = &driver_read_table,
-+      .wr_table = &driver_write_table,
-+};
-+EXPORT_SYMBOL(fxos8700_regmap_config);
-+
-+#define FXOS8700_CHANNEL(_type, _axis) {                      \
-+      .type = _type,                                          \
-+      .modified = 1,                                          \
-+      .channel2 = IIO_MOD_##_axis,                            \
-+      .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),           \
-+      .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |  \
-+              BIT(IIO_CHAN_INFO_SAMP_FREQ),                   \
-+}
-+
-+enum fxos8700_accel_scale_bits {
-+      MODE_2G = 0,
-+      MODE_4G,
-+      MODE_8G,
-+};
-+
-+/* scan indexes follow DATA register order */
-+enum fxos8700_scan_axis {
-+      FXOS8700_SCAN_ACCEL_X = 0,
-+      FXOS8700_SCAN_ACCEL_Y,
-+      FXOS8700_SCAN_ACCEL_Z,
-+      FXOS8700_SCAN_MAGN_X,
-+      FXOS8700_SCAN_MAGN_Y,
-+      FXOS8700_SCAN_MAGN_Z,
-+      FXOS8700_SCAN_RHALL,
-+      FXOS8700_SCAN_TIMESTAMP,
-+};
-+
-+enum fxos8700_sensor {
-+      FXOS8700_ACCEL  = 0,
-+      FXOS8700_MAGN,
-+      FXOS8700_NUM_SENSORS /* must be last */
-+};
-+
-+enum fxos8700_int_pin {
-+      FXOS8700_PIN_INT1,
-+      FXOS8700_PIN_INT2
-+};
-+
-+struct fxos8700_scale {
-+      u8 bits;
-+      int uscale;
-+};
-+
-+struct fxos8700_odr {
-+      u8 bits;
-+      int odr;
-+      int uodr;
-+};
-+
-+static const struct fxos8700_scale fxos8700_accel_scale[] = {
-+      { MODE_2G, 244},
-+      { MODE_4G, 488},
-+      { MODE_8G, 976},
-+};
-+
-+/*
-+ * Accellerometer and magnetometer have the same ODR options, set in the
-+ * CTRL_REG1 register. ODR is halved when using both sensors at once in
-+ * hybrid mode.
-+ */
-+static const struct fxos8700_odr fxos8700_odr[] = {
-+      {0x00, 800, 0},
-+      {0x01, 400, 0},
-+      {0x02, 200, 0},
-+      {0x03, 100, 0},
-+      {0x04, 50, 0},
-+      {0x05, 12, 500000},
-+      {0x06, 6, 250000},
-+      {0x07, 1, 562500},
-+};
-+
-+static const struct iio_chan_spec fxos8700_channels[] = {
-+      FXOS8700_CHANNEL(IIO_ACCEL, X),
-+      FXOS8700_CHANNEL(IIO_ACCEL, Y),
-+      FXOS8700_CHANNEL(IIO_ACCEL, Z),
-+      FXOS8700_CHANNEL(IIO_MAGN, X),
-+      FXOS8700_CHANNEL(IIO_MAGN, Y),
-+      FXOS8700_CHANNEL(IIO_MAGN, Z),
-+      IIO_CHAN_SOFT_TIMESTAMP(FXOS8700_SCAN_TIMESTAMP),
-+};
-+
-+static enum fxos8700_sensor fxos8700_to_sensor(enum iio_chan_type iio_type)
-+{
-+      switch (iio_type) {
-+      case IIO_ACCEL:
-+              return FXOS8700_ACCEL;
-+      case IIO_ANGL_VEL:
-+              return FXOS8700_MAGN;
-+      default:
-+              return -EINVAL;
-+      }
-+}
-+
-+static int fxos8700_set_active_mode(struct fxos8700_data *data,
-+                                  enum fxos8700_sensor t, bool mode)
-+{
-+      int ret;
-+
-+      ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1, mode);
-+      if (ret)
-+              return ret;
-+
-+      usleep_range(FXOS8700_ACTIVE_MIN_USLEEP,
-+                   FXOS8700_ACTIVE_MIN_USLEEP + 1000);
-+
-+      return 0;
-+}
-+
-+static int fxos8700_set_scale(struct fxos8700_data *data,
-+                            enum fxos8700_sensor t, int uscale)
-+{
-+      int i;
-+      static const int scale_num = ARRAY_SIZE(fxos8700_accel_scale);
-+      struct device *dev = regmap_get_device(data->regmap);
-+
-+      if (t == FXOS8700_MAGN) {
-+              dev_err(dev, "Magnetometer scale is locked at 1200uT\n");
-+              return -EINVAL;
-+      }
-+
-+      for (i = 0; i < scale_num; i++)
-+              if (fxos8700_accel_scale[i].uscale == uscale)
-+                      break;
-+
-+      if (i == scale_num)
-+              return -EINVAL;
-+
-+      return regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG,
-+                          fxos8700_accel_scale[i].bits);
-+}
-+
-+static int fxos8700_get_scale(struct fxos8700_data *data,
-+                            enum fxos8700_sensor t, int *uscale)
-+{
-+      int i, ret, val;
-+      static const int scale_num = ARRAY_SIZE(fxos8700_accel_scale);
-+
-+      if (t == FXOS8700_MAGN) {
-+              *uscale = 1200; /* Magnetometer is locked at 1200uT */
-+              return 0;
-+      }
-+
-+      ret = regmap_read(data->regmap, FXOS8700_XYZ_DATA_CFG, &val);
-+      if (ret)
-+              return ret;
-+
-+      for (i = 0; i < scale_num; i++) {
-+              if (fxos8700_accel_scale[i].bits == (val & 0x3)) {
-+                      *uscale = fxos8700_accel_scale[i].uscale;
-+                      return 0;
-+              }
-+      }
-+
-+      return -EINVAL;
-+}
-+
-+static int fxos8700_get_data(struct fxos8700_data *data, int chan_type,
-+                           int axis, int *val)
-+{
-+      u8 base, reg;
-+      int ret;
-+      enum fxos8700_sensor type = fxos8700_to_sensor(chan_type);
-+
-+      base = type ? FXOS8700_OUT_X_MSB : FXOS8700_M_OUT_X_MSB;
-+
-+      /* Block read 6 bytes of device output registers to avoid data loss */
-+      ret = regmap_bulk_read(data->regmap, base, data->buf,
-+                             FXOS8700_DATA_BUF_SIZE);
-+      if (ret)
-+              return ret;
-+
-+      /* Convert axis to buffer index */
-+      reg = axis - IIO_MOD_X;
-+
-+      /* Convert to native endianness */
-+      *val = sign_extend32(be16_to_cpu(data->buf[reg]), 15);
-+
-+      return 0;
-+}
-+
-+static int fxos8700_set_odr(struct fxos8700_data *data, enum fxos8700_sensor t,
-+                          int odr, int uodr)
-+{
-+      int i, ret, val;
-+      bool active_mode;
-+      static const int odr_num = ARRAY_SIZE(fxos8700_odr);
-+
-+      ret = regmap_read(data->regmap, FXOS8700_CTRL_REG1, &val);
-+      if (ret)
-+              return ret;
-+
-+      active_mode = val & FXOS8700_ACTIVE;
-+
-+      if (active_mode) {
-+              /*
-+               * The device must be in standby mode to change any of the
-+               * other fields within CTRL_REG1
-+               */
-+              ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1,
-+                                 val & ~FXOS8700_ACTIVE);
-+              if (ret)
-+                      return ret;
-+      }
-+
-+      for (i = 0; i < odr_num; i++)
-+              if (fxos8700_odr[i].odr == odr && fxos8700_odr[i].uodr == uodr)
-+                      break;
-+
-+      if (i >= odr_num)
-+              return -EINVAL;
-+
-+      return regmap_update_bits(data->regmap,
-+                                FXOS8700_CTRL_REG1,
-+                                FXOS8700_CTRL_ODR_MSK + FXOS8700_ACTIVE,
-+                                fxos8700_odr[i].bits << 3 | active_mode);
-+}
-+
-+static int fxos8700_get_odr(struct fxos8700_data *data, enum fxos8700_sensor t,
-+                          int *odr, int *uodr)
-+{
-+      int i, val, ret;
-+      static const int odr_num = ARRAY_SIZE(fxos8700_odr);
-+
-+      ret = regmap_read(data->regmap, FXOS8700_CTRL_REG1, &val);
-+      if (ret)
-+              return ret;
-+
-+      val &= FXOS8700_CTRL_ODR_MSK;
-+
-+      for (i = 0; i < odr_num; i++)
-+              if (val == fxos8700_odr[i].bits)
-+                      break;
-+
-+      if (i >= odr_num)
-+              return -EINVAL;
-+
-+      *odr = fxos8700_odr[i].odr;
-+      *uodr = fxos8700_odr[i].uodr;
-+
-+      return 0;
-+}
-+
-+static int fxos8700_read_raw(struct iio_dev *indio_dev,
-+                           struct iio_chan_spec const *chan,
-+                           int *val, int *val2, long mask)
-+{
-+      int ret;
-+      struct fxos8700_data *data = iio_priv(indio_dev);
-+
-+      switch (mask) {
-+      case IIO_CHAN_INFO_RAW:
-+              ret = fxos8700_get_data(data, chan->type, chan->channel2, val);
-+              if (ret)
-+                      return ret;
-+              return IIO_VAL_INT;
-+      case IIO_CHAN_INFO_SCALE:
-+              *val = 0;
-+              ret = fxos8700_get_scale(data, fxos8700_to_sensor(chan->type),
-+                                       val2);
-+              return ret ? ret : IIO_VAL_INT_PLUS_MICRO;
-+      case IIO_CHAN_INFO_SAMP_FREQ:
-+              ret = fxos8700_get_odr(data, fxos8700_to_sensor(chan->type),
-+                                     val, val2);
-+              return ret ? ret : IIO_VAL_INT_PLUS_MICRO;
-+      default:
-+              return -EINVAL;
-+      }
-+}
-+
-+static int fxos8700_write_raw(struct iio_dev *indio_dev,
-+                            struct iio_chan_spec const *chan,
-+                            int val, int val2, long mask)
-+{
-+      struct fxos8700_data *data = iio_priv(indio_dev);
-+
-+      switch (mask) {
-+      case IIO_CHAN_INFO_SCALE:
-+              return fxos8700_set_scale(data, fxos8700_to_sensor(chan->type),
-+                                        val2);
-+      case IIO_CHAN_INFO_SAMP_FREQ:
-+              return fxos8700_set_odr(data, fxos8700_to_sensor(chan->type),
-+                                      val, val2);
-+      default:
-+              return -EINVAL;
-+      }
-+}
-+
-+static IIO_CONST_ATTR(in_accel_sampling_frequency_available,
-+                    "1.5625 6.25 12.5 50 100 200 400 800");
-+static IIO_CONST_ATTR(in_magn_sampling_frequency_available,
-+                    "1.5625 6.25 12.5 50 100 200 400 800");
-+static IIO_CONST_ATTR(in_accel_scale_available, "0.000244 0.000488 0.000976");
-+static IIO_CONST_ATTR(in_magn_scale_available, "0.000001200");
-+
-+static struct attribute *fxos8700_attrs[] = {
-+      &iio_const_attr_in_accel_sampling_frequency_available.dev_attr.attr,
-+      &iio_const_attr_in_magn_sampling_frequency_available.dev_attr.attr,
-+      &iio_const_attr_in_accel_scale_available.dev_attr.attr,
-+      &iio_const_attr_in_magn_scale_available.dev_attr.attr,
-+      NULL,
-+};
-+
-+static const struct attribute_group fxos8700_attrs_group = {
-+      .attrs = fxos8700_attrs,
-+};
-+
-+static const struct iio_info fxos8700_info = {
-+      .read_raw = fxos8700_read_raw,
-+      .write_raw = fxos8700_write_raw,
-+      .attrs = &fxos8700_attrs_group,
-+};
-+
-+static int fxos8700_chip_init(struct fxos8700_data *data, bool use_spi)
-+{
-+      int ret;
-+      unsigned int val;
-+      struct device *dev = regmap_get_device(data->regmap);
-+
-+      ret = regmap_read(data->regmap, FXOS8700_WHO_AM_I, &val);
-+      if (ret) {
-+              dev_err(dev, "Error reading chip id\n");
-+              return ret;
-+      }
-+      if (val != FXOS8700_DEVICE_ID && val != FXOS8700_PRE_DEVICE_ID) {
-+              dev_err(dev, "Wrong chip id, got %x expected %x or %x\n",
-+                      val, FXOS8700_DEVICE_ID, FXOS8700_PRE_DEVICE_ID);
-+              return -ENODEV;
-+      }
-+
-+      ret = fxos8700_set_active_mode(data, FXOS8700_ACCEL, true);
-+      if (ret)
-+              return ret;
-+
-+      ret = fxos8700_set_active_mode(data, FXOS8700_MAGN, true);
-+      if (ret)
-+              return ret;
-+
-+      /*
-+       * The device must be in standby mode to change any of the other fields
-+       * within CTRL_REG1
-+       */
-+      ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1, 0x00);
-+      if (ret)
-+              return ret;
-+
-+      /* Set max oversample ratio (OSR) and both devices active */
-+      ret = regmap_write(data->regmap, FXOS8700_M_CTRL_REG1,
-+                         FXOS8700_HMS_MASK | FXOS8700_OS_MASK);
-+      if (ret)
-+              return ret;
-+
-+      /* Disable and rst min/max measurements & threshold */
-+      ret = regmap_write(data->regmap, FXOS8700_M_CTRL_REG2,
-+                         FXOS8700_MAXMIN_RST | FXOS8700_MAXMIN_DIS_THS |
-+                         FXOS8700_MAXMIN_DIS);
-+      if (ret)
-+              return ret;
-+
-+      /* Max ODR (800Hz individual or 400Hz hybrid), active mode */
-+      ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1,
-+                         FXOS8700_CTRL_ODR_MAX | FXOS8700_ACTIVE);
-+      if (ret)
-+              return ret;
-+
-+      /* Set for max full-scale range (+/-8G) */
-+      return regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG, MODE_8G);
-+}
-+
-+static void fxos8700_chip_uninit(void *data)
-+{
-+      struct fxos8700_data *fxos8700_data = data;
-+
-+      fxos8700_set_active_mode(fxos8700_data, FXOS8700_ACCEL, false);
-+      fxos8700_set_active_mode(fxos8700_data, FXOS8700_MAGN, false);
-+}
-+
-+int fxos8700_core_probe(struct device *dev, struct regmap *regmap,
-+                      const char *name, bool use_spi)
-+{
-+      struct iio_dev *indio_dev;
-+      struct fxos8700_data *data;
-+      int ret;
-+
-+      indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
-+      if (!indio_dev)
-+              return -ENOMEM;
-+
-+      data = iio_priv(indio_dev);
-+      dev_set_drvdata(dev, indio_dev);
-+      data->regmap = regmap;
-+
-+      ret = fxos8700_chip_init(data, use_spi);
-+      if (ret)
-+              return ret;
-+
-+      ret = devm_add_action_or_reset(dev, fxos8700_chip_uninit, data);
-+      if (ret)
-+              return ret;
-+
-+      indio_dev->dev.parent = dev;
-+      indio_dev->channels = fxos8700_channels;
-+      indio_dev->num_channels = ARRAY_SIZE(fxos8700_channels);
-+      indio_dev->name = name ? name : "fxos8700";
-+      indio_dev->modes = INDIO_DIRECT_MODE;
-+      indio_dev->info = &fxos8700_info;
-+
-+      return devm_iio_device_register(dev, indio_dev);
-+}
-+EXPORT_SYMBOL_GPL(fxos8700_core_probe);
-+
-+MODULE_AUTHOR("Robert Jones <rjones@gateworks.com>");
-+MODULE_DESCRIPTION("FXOS8700 6-Axis Acc and Mag Combo Sensor driver");
-+MODULE_LICENSE("GPL v2");
---- /dev/null
-+++ b/drivers/iio/imu/fxos8700_i2c.c
-@@ -0,0 +1,71 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * FXOS8700 - NXP IMU, I2C bits
-+ *
-+ * 7-bit I2C slave address determined by SA1 and SA0 logic level
-+ * inputs represented in the following table:
-+ *      SA1  |  SA0  |  Slave Address
-+ *      0    |  0    |  0x1E
-+ *      0    |  1    |  0x1D
-+ *      1    |  0    |  0x1C
-+ *      1    |  1    |  0x1F
-+ */
-+#include <linux/acpi.h>
-+#include <linux/i2c.h>
-+#include <linux/module.h>
-+#include <linux/mod_devicetable.h>
-+#include <linux/regmap.h>
-+
-+#include "fxos8700.h"
-+
-+static int fxos8700_i2c_probe(struct i2c_client *client,
-+                            const struct i2c_device_id *id)
-+{
-+      struct regmap *regmap;
-+      const char *name = NULL;
-+
-+      regmap = devm_regmap_init_i2c(client, &fxos8700_regmap_config);
-+      if (IS_ERR(regmap)) {
-+              dev_err(&client->dev, "Failed to register i2c regmap %d\n",
-+                      (int)PTR_ERR(regmap));
-+              return PTR_ERR(regmap);
-+      }
-+
-+      if (id)
-+              name = id->name;
-+
-+      return fxos8700_core_probe(&client->dev, regmap, name, false);
-+}
-+
-+static const struct i2c_device_id fxos8700_i2c_id[] = {
-+      {"fxos8700", 0},
-+      { }
-+};
-+MODULE_DEVICE_TABLE(i2c, fxos8700_i2c_id);
-+
-+static const struct acpi_device_id fxos8700_acpi_match[] = {
-+      {"FXOS8700", 0},
-+      { }
-+};
-+MODULE_DEVICE_TABLE(acpi, fxos8700_acpi_match);
-+
-+static const struct of_device_id fxos8700_of_match[] = {
-+      { .compatible = "nxp,fxos8700" },
-+      { }
-+};
-+MODULE_DEVICE_TABLE(of, fxos8700_of_match);
-+
-+static struct i2c_driver fxos8700_i2c_driver = {
-+      .driver = {
-+              .name                   = "fxos8700_i2c",
-+              .acpi_match_table       = ACPI_PTR(fxos8700_acpi_match),
-+              .of_match_table         = fxos8700_of_match,
-+      },
-+      .probe          = fxos8700_i2c_probe,
-+      .id_table       = fxos8700_i2c_id,
-+};
-+module_i2c_driver(fxos8700_i2c_driver);
-+
-+MODULE_AUTHOR("Robert Jones <rjones@gateworks.com>");
-+MODULE_DESCRIPTION("FXOS8700 I2C driver");
-+MODULE_LICENSE("GPL v2");
---- /dev/null
-+++ b/drivers/iio/imu/fxos8700_spi.c
-@@ -0,0 +1,59 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * FXOS8700 - NXP IMU, SPI bits
-+ */
-+#include <linux/acpi.h>
-+#include <linux/module.h>
-+#include <linux/mod_devicetable.h>
-+#include <linux/regmap.h>
-+#include <linux/spi/spi.h>
-+
-+#include "fxos8700.h"
-+
-+static int fxos8700_spi_probe(struct spi_device *spi)
-+{
-+      struct regmap *regmap;
-+      const struct spi_device_id *id = spi_get_device_id(spi);
-+
-+      regmap = devm_regmap_init_spi(spi, &fxos8700_regmap_config);
-+      if (IS_ERR(regmap)) {
-+              dev_err(&spi->dev, "Failed to register spi regmap %d\n",
-+                      (int)PTR_ERR(regmap));
-+              return PTR_ERR(regmap);
-+      }
-+
-+      return fxos8700_core_probe(&spi->dev, regmap, id->name, true);
-+}
-+
-+static const struct spi_device_id fxos8700_spi_id[] = {
-+      {"fxos8700", 0},
-+      { }
-+};
-+MODULE_DEVICE_TABLE(spi, fxos8700_spi_id);
-+
-+static const struct acpi_device_id fxos8700_acpi_match[] = {
-+      {"FXOS8700", 0},
-+      { }
-+};
-+MODULE_DEVICE_TABLE(acpi, fxos8700_acpi_match);
-+
-+static const struct of_device_id fxos8700_of_match[] = {
-+      { .compatible = "nxp,fxos8700" },
-+      { }
-+};
-+MODULE_DEVICE_TABLE(of, fxos8700_of_match);
-+
-+static struct spi_driver fxos8700_spi_driver = {
-+      .probe          = fxos8700_spi_probe,
-+      .id_table       = fxos8700_spi_id,
-+      .driver = {
-+              .acpi_match_table       = ACPI_PTR(fxos8700_acpi_match),
-+              .of_match_table         = fxos8700_of_match,
-+              .name                   = "fxos8700_spi",
-+      },
-+};
-+module_spi_driver(fxos8700_spi_driver);
-+
-+MODULE_AUTHOR("Robert Jones <rjones@gateworks.com>");
-+MODULE_DESCRIPTION("FXOS8700 SPI driver");
-+MODULE_LICENSE("GPL v2");