summaryrefslogtreecommitdiffstats
path: root/drivers/iio/accel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-03-28 12:27:35 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2022-03-28 12:27:35 -0700
commit02e2af20f4f9f2aa0c84e9a30a35c02f0fbb7daa (patch)
treed126449a7d2ea2270627183f7cebd726fbe56a9d /drivers/iio/accel
parentff61bc81b3feebcef4d0431a92e2e40e8d4fe8b3 (diff)
parent37fd83916da2e4cae03d350015c82a67b1b334c4 (diff)
downloadlinux-02e2af20f4f9f2aa0c84e9a30a35c02f0fbb7daa.tar.bz2
Merge tag 'char-misc-5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc and other driver updates from Greg KH: "Here is the big set of char/misc and other small driver subsystem updates for 5.18-rc1. Included in here are merges from driver subsystems which contain: - iio driver updates and new drivers - fsi driver updates - fpga driver updates - habanalabs driver updates and support for new hardware - soundwire driver updates and new drivers - phy driver updates and new drivers - coresight driver updates - icc driver updates Individual changes include: - mei driver updates - interconnect driver updates - new PECI driver subsystem added - vmci driver updates - lots of tiny misc/char driver updates All of these have been in linux-next for a while with no reported problems" * tag 'char-misc-5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (556 commits) firmware: google: Properly state IOMEM dependency kgdbts: fix return value of __setup handler firmware: sysfb: fix platform-device leak in error path firmware: stratix10-svc: add missing callback parameter on RSU arm64: dts: qcom: add non-secure domain property to fastrpc nodes misc: fastrpc: Add dma handle implementation misc: fastrpc: Add fdlist implementation misc: fastrpc: Add helper function to get list and page misc: fastrpc: Add support to secure memory map dt-bindings: misc: add fastrpc domain vmid property misc: fastrpc: check before loading process to the DSP misc: fastrpc: add secure domain support dt-bindings: misc: add property to support non-secure DSP misc: fastrpc: Add support to get DSP capabilities misc: fastrpc: add support for FASTRPC_IOCTL_MEM_MAP/UNMAP misc: fastrpc: separate fastrpc device from channel context dt-bindings: nvmem: brcm,nvram: add basic NVMEM cells dt-bindings: nvmem: make "reg" property optional nvmem: brcm_nvram: parse NVRAM content into NVMEM cells nvmem: dt-bindings: Fix the error of dt-bindings check ...
Diffstat (limited to 'drivers/iio/accel')
-rw-r--r--drivers/iio/accel/Kconfig62
-rw-r--r--drivers/iio/accel/Makefile3
-rw-r--r--drivers/iio/accel/adis16201.c1
-rw-r--r--drivers/iio/accel/adis16209.c1
-rw-r--r--drivers/iio/accel/adxl313_core.c6
-rw-r--r--drivers/iio/accel/adxl313_i2c.c1
-rw-r--r--drivers/iio/accel/adxl313_spi.c1
-rw-r--r--drivers/iio/accel/adxl345.h7
-rw-r--r--drivers/iio/accel/adxl345_core.c56
-rw-r--r--drivers/iio/accel/adxl345_i2c.c35
-rw-r--r--drivers/iio/accel/adxl345_spi.c35
-rw-r--r--drivers/iio/accel/adxl355_core.c11
-rw-r--r--drivers/iio/accel/adxl355_i2c.c1
-rw-r--r--drivers/iio/accel/adxl355_spi.c1
-rw-r--r--drivers/iio/accel/adxl367.c1588
-rw-r--r--drivers/iio/accel/adxl367.h23
-rw-r--r--drivers/iio/accel/adxl367_i2c.c90
-rw-r--r--drivers/iio/accel/adxl367_spi.c164
-rw-r--r--drivers/iio/accel/adxl372.c4
-rw-r--r--drivers/iio/accel/adxl372_i2c.c1
-rw-r--r--drivers/iio/accel/adxl372_spi.c1
-rw-r--r--drivers/iio/accel/bma180.c9
-rw-r--r--drivers/iio/accel/bma400_core.c6
-rw-r--r--drivers/iio/accel/bma400_i2c.c1
-rw-r--r--drivers/iio/accel/bma400_spi.c1
-rw-r--r--drivers/iio/accel/bmc150-accel-core.c8
-rw-r--r--drivers/iio/accel/bmc150-accel-i2c.c1
-rw-r--r--drivers/iio/accel/bmc150-accel-spi.c1
-rw-r--r--drivers/iio/accel/bmi088-accel-core.c8
-rw-r--r--drivers/iio/accel/bmi088-accel-spi.c1
-rw-r--r--drivers/iio/accel/da280.c6
-rw-r--r--drivers/iio/accel/da311.c6
-rw-r--r--drivers/iio/accel/dmard06.c10
-rw-r--r--drivers/iio/accel/dmard09.c2
-rw-r--r--drivers/iio/accel/dmard10.c7
-rw-r--r--drivers/iio/accel/fxls8962af-core.c8
-rw-r--r--drivers/iio/accel/fxls8962af-i2c.c1
-rw-r--r--drivers/iio/accel/fxls8962af-spi.c1
-rw-r--r--drivers/iio/accel/kxsd9-i2c.c1
-rw-r--r--drivers/iio/accel/kxsd9-spi.c1
-rw-r--r--drivers/iio/accel/kxsd9.c6
-rw-r--r--drivers/iio/accel/mc3230.c6
-rw-r--r--drivers/iio/accel/mma7455_core.c6
-rw-r--r--drivers/iio/accel/mma7455_i2c.c1
-rw-r--r--drivers/iio/accel/mma7455_spi.c1
-rw-r--r--drivers/iio/accel/mma7660.c11
-rw-r--r--drivers/iio/accel/mma8452.c54
-rw-r--r--drivers/iio/accel/mma9551.c12
-rw-r--r--drivers/iio/accel/mma9551_core.c36
-rw-r--r--drivers/iio/accel/mma9553.c12
-rw-r--r--drivers/iio/accel/ssp_accel_sensor.c1
-rw-r--r--drivers/iio/accel/st_accel.h2
-rw-r--r--drivers/iio/accel/st_accel_buffer.c5
-rw-r--r--drivers/iio/accel/st_accel_core.c88
-rw-r--r--drivers/iio/accel/st_accel_i2c.c6
-rw-r--r--drivers/iio/accel/st_accel_spi.c1
-rw-r--r--drivers/iio/accel/stk8312.c11
-rw-r--r--drivers/iio/accel/stk8ba50.c11
58 files changed, 2221 insertions, 220 deletions
diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 49587c992a6d..eac3f02662ae 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -123,6 +123,33 @@ config ADXL355_SPI
will be called adxl355_spi and you will also get adxl355_core
for the core module.
+config ADXL367
+ tristate
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+
+config ADXL367_SPI
+ tristate "Analog Devices ADXL367 3-Axis Accelerometer SPI Driver"
+ depends on SPI
+ select ADXL367
+ select REGMAP_SPI
+ help
+ Say yes here to add support for the Analog Devices ADXL367 triaxial
+ acceleration sensor.
+ To compile this driver as a module, choose M here: the
+ module will be called adxl367_spi.
+
+config ADXL367_I2C
+ tristate "Analog Devices ADXL367 3-Axis Accelerometer I2C Driver"
+ depends on I2C
+ select ADXL367
+ select REGMAP_I2C
+ help
+ Say yes here to add support for the Analog Devices ADXL367 triaxial
+ acceleration sensor.
+ To compile this driver as a module, choose M here: the
+ module will be called adxl367_i2c.
+
config ADXL372
tristate
select IIO_BUFFER
@@ -349,8 +376,6 @@ config IIO_ST_ACCEL_3AXIS
depends on !SENSORS_LIS3_I2C
depends on !SENSORS_LIS3_SPI
select IIO_ST_SENSORS_CORE
- select IIO_ST_ACCEL_I2C_3AXIS if (I2C)
- select IIO_ST_ACCEL_SPI_3AXIS if (SPI_MASTER)
select IIO_TRIGGERED_BUFFER if (IIO_BUFFER)
help
Say yes here to build support for STMicroelectronics accelerometers:
@@ -358,23 +383,30 @@ config IIO_ST_ACCEL_3AXIS
LIS331DLH, LSM303DL, LSM303DLM, LSM330, LIS2DH12, H3LIS331DL,
LNG2DM, LIS3DE, LIS2DE12, LIS2HH12
- This driver can also be built as a module. If so, these modules
- will be created:
- - st_accel (core functions for the driver [it is mandatory]);
- - st_accel_i2c (necessary for the I2C devices [optional*]);
- - st_accel_spi (necessary for the SPI devices [optional*]);
-
- (*) one of these is necessary to do something.
+ Also need to enable at least one of I2C and SPI interface drivers
+ below.
config IIO_ST_ACCEL_I2C_3AXIS
- tristate
- depends on IIO_ST_ACCEL_3AXIS
- depends on IIO_ST_SENSORS_I2C
+ tristate "STMicroelectronics accelerometers 3-Axis I2C Interface"
+ depends on I2C && IIO_ST_ACCEL_3AXIS
+ default I2C && IIO_ST_ACCEL_3AXIS
+ select IIO_ST_SENSORS_I2C
+ help
+ Build support for STMicroelectronics accelerometers I2C interface.
+
+ To compile this driver as a module, choose M here. The module
+ will be called st_accel_i2c.
config IIO_ST_ACCEL_SPI_3AXIS
- tristate
- depends on IIO_ST_ACCEL_3AXIS
- depends on IIO_ST_SENSORS_SPI
+ tristate "STMicroelectronics accelerometers 3-Axis SPI Interface"
+ depends on SPI_MASTER && IIO_ST_ACCEL_3AXIS
+ default SPI_MASTER && IIO_ST_ACCEL_3AXIS
+ select IIO_ST_SENSORS_SPI
+ help
+ Build support for STMicroelectronics accelerometers SPI interface.
+
+ To compile this driver as a module, choose M here. The module
+ will be called st_accel_spi.
config KXSD9
tristate "Kionix KXSD9 Accelerometer Driver"
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index d03e2f6bba08..4d8792668838 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -15,6 +15,9 @@ obj-$(CONFIG_ADXL345_SPI) += adxl345_spi.o
obj-$(CONFIG_ADXL355) += adxl355_core.o
obj-$(CONFIG_ADXL355_I2C) += adxl355_i2c.o
obj-$(CONFIG_ADXL355_SPI) += adxl355_spi.o
+obj-$(CONFIG_ADXL367) += adxl367.o
+obj-$(CONFIG_ADXL367_I2C) += adxl367_i2c.o
+obj-$(CONFIG_ADXL367_SPI) += adxl367_spi.o
obj-$(CONFIG_ADXL372) += adxl372.o
obj-$(CONFIG_ADXL372_I2C) += adxl372_i2c.o
obj-$(CONFIG_ADXL372_SPI) += adxl372_spi.o
diff --git a/drivers/iio/accel/adis16201.c b/drivers/iio/accel/adis16201.c
index 7a434e2884d4..dfb8e2e5bdf5 100644
--- a/drivers/iio/accel/adis16201.c
+++ b/drivers/iio/accel/adis16201.c
@@ -300,3 +300,4 @@ MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
MODULE_DESCRIPTION("Analog Devices ADIS16201 Dual-Axis Digital Inclinometer and Accelerometer");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("spi:adis16201");
+MODULE_IMPORT_NS(IIO_ADISLIB);
diff --git a/drivers/iio/accel/adis16209.c b/drivers/iio/accel/adis16209.c
index ac08e866d612..5a9c6e2296f1 100644
--- a/drivers/iio/accel/adis16209.c
+++ b/drivers/iio/accel/adis16209.c
@@ -310,3 +310,4 @@ MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
MODULE_DESCRIPTION("Analog Devices ADIS16209 Dual-Axis Digital Inclinometer and Accelerometer");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("spi:adis16209");
+MODULE_IMPORT_NS(IIO_ADISLIB);
diff --git a/drivers/iio/accel/adxl313_core.c b/drivers/iio/accel/adxl313_core.c
index 0d243341f1a7..9e4193e64765 100644
--- a/drivers/iio/accel/adxl313_core.c
+++ b/drivers/iio/accel/adxl313_core.c
@@ -26,7 +26,7 @@ const struct regmap_access_table adxl313_readable_regs_table = {
.yes_ranges = adxl313_readable_reg_range,
.n_yes_ranges = ARRAY_SIZE(adxl313_readable_reg_range),
};
-EXPORT_SYMBOL_GPL(adxl313_readable_regs_table);
+EXPORT_SYMBOL_NS_GPL(adxl313_readable_regs_table, IIO_ADXL313);
static const struct regmap_range adxl313_writable_reg_range[] = {
regmap_reg_range(ADXL313_REG_SOFT_RESET, ADXL313_REG_SOFT_RESET),
@@ -41,7 +41,7 @@ const struct regmap_access_table adxl313_writable_regs_table = {
.yes_ranges = adxl313_writable_reg_range,
.n_yes_ranges = ARRAY_SIZE(adxl313_writable_reg_range),
};
-EXPORT_SYMBOL_GPL(adxl313_writable_regs_table);
+EXPORT_SYMBOL_NS_GPL(adxl313_writable_regs_table, IIO_ADXL313);
struct adxl313_data {
struct regmap *regmap;
@@ -325,7 +325,7 @@ int adxl313_core_probe(struct device *dev,
return devm_iio_device_register(dev, indio_dev);
}
-EXPORT_SYMBOL_GPL(adxl313_core_probe);
+EXPORT_SYMBOL_NS_GPL(adxl313_core_probe, IIO_ADXL313);
MODULE_AUTHOR("Lucas Stankus <lucas.p.stankus@gmail.com>");
MODULE_DESCRIPTION("ADXL313 3-Axis Digital Accelerometer core driver");
diff --git a/drivers/iio/accel/adxl313_i2c.c b/drivers/iio/accel/adxl313_i2c.c
index 82e9fb2db1e6..c329765dbf60 100644
--- a/drivers/iio/accel/adxl313_i2c.c
+++ b/drivers/iio/accel/adxl313_i2c.c
@@ -64,3 +64,4 @@ module_i2c_driver(adxl313_i2c_driver);
MODULE_AUTHOR("Lucas Stankus <lucas.p.stankus@gmail.com>");
MODULE_DESCRIPTION("ADXL313 3-Axis Digital Accelerometer I2C driver");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS(IIO_ADXL313);
diff --git a/drivers/iio/accel/adxl313_spi.c b/drivers/iio/accel/adxl313_spi.c
index a6162f36ef52..a3c6d553462d 100644
--- a/drivers/iio/accel/adxl313_spi.c
+++ b/drivers/iio/accel/adxl313_spi.c
@@ -90,3 +90,4 @@ module_spi_driver(adxl313_spi_driver);
MODULE_AUTHOR("Lucas Stankus <lucas.p.stankus@gmail.com>");
MODULE_DESCRIPTION("ADXL313 3-Axis Digital Accelerometer SPI driver");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS(IIO_ADXL313);
diff --git a/drivers/iio/accel/adxl345.h b/drivers/iio/accel/adxl345.h
index af0fdd02c4f2..d7e67cb08538 100644
--- a/drivers/iio/accel/adxl345.h
+++ b/drivers/iio/accel/adxl345.h
@@ -9,11 +9,10 @@
#define _ADXL345_H_
enum adxl345_device_type {
- ADXL345,
- ADXL375,
+ ADXL345 = 1,
+ ADXL375 = 2,
};
-int adxl345_core_probe(struct device *dev, struct regmap *regmap,
- enum adxl345_device_type type, const char *name);
+int adxl345_core_probe(struct device *dev, struct regmap *regmap);
#endif /* _ADXL345_H_ */
diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c
index 4b275051ef61..370bfec1275a 100644
--- a/drivers/iio/accel/adxl345_core.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -8,6 +8,7 @@
*/
#include <linux/module.h>
+#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/iio/iio.h>
@@ -194,7 +195,7 @@ static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
static struct attribute *adxl345_attrs[] = {
&iio_const_attr_sampling_frequency_available.dev_attr.attr,
- NULL,
+ NULL
};
static const struct attribute_group adxl345_attrs_group = {
@@ -208,30 +209,44 @@ static const struct iio_info adxl345_info = {
.write_raw_get_fmt = adxl345_write_raw_get_fmt,
};
+static int adxl345_powerup(void *regmap)
+{
+ return regmap_write(regmap, ADXL345_REG_POWER_CTL, ADXL345_POWER_CTL_MEASURE);
+}
+
static void adxl345_powerdown(void *regmap)
{
regmap_write(regmap, ADXL345_REG_POWER_CTL, ADXL345_POWER_CTL_STANDBY);
}
-int adxl345_core_probe(struct device *dev, struct regmap *regmap,
- enum adxl345_device_type type, const char *name)
+int adxl345_core_probe(struct device *dev, struct regmap *regmap)
{
+ enum adxl345_device_type type;
struct adxl345_data *data;
struct iio_dev *indio_dev;
+ const char *name;
u32 regval;
int ret;
- ret = regmap_read(regmap, ADXL345_REG_DEVID, &regval);
- if (ret < 0) {
- dev_err(dev, "Error reading device ID: %d\n", ret);
- return ret;
+ type = (uintptr_t)device_get_match_data(dev);
+ switch (type) {
+ case ADXL345:
+ name = "adxl345";
+ break;
+ case ADXL375:
+ name = "adxl375";
+ break;
+ default:
+ return -EINVAL;
}
- if (regval != ADXL345_DEVID) {
- dev_err(dev, "Invalid device ID: %x, expected %x\n",
- regval, ADXL345_DEVID);
- return -ENODEV;
- }
+ ret = regmap_read(regmap, ADXL345_REG_DEVID, &regval);
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "Error reading device ID\n");
+
+ if (regval != ADXL345_DEVID)
+ return dev_err_probe(dev, -ENODEV, "Invalid device ID: %x, expected %x\n",
+ regval, ADXL345_DEVID);
indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
if (!indio_dev)
@@ -245,10 +260,8 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap,
ret = regmap_write(data->regmap, ADXL345_REG_DATA_FORMAT,
data->data_range);
- if (ret < 0) {
- dev_err(dev, "Failed to set data range: %d\n", ret);
- return ret;
- }
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "Failed to set data range\n");
indio_dev->name = name;
indio_dev->info = &adxl345_info;
@@ -257,12 +270,9 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap,
indio_dev->num_channels = ARRAY_SIZE(adxl345_channels);
/* Enable measurement mode */
- ret = regmap_write(data->regmap, ADXL345_REG_POWER_CTL,
- ADXL345_POWER_CTL_MEASURE);
- if (ret < 0) {
- dev_err(dev, "Failed to enable measurement mode: %d\n", ret);
- return ret;
- }
+ ret = adxl345_powerup(data->regmap);
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "Failed to enable measurement mode\n");
ret = devm_add_action_or_reset(dev, adxl345_powerdown, data->regmap);
if (ret < 0)
@@ -270,7 +280,7 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap,
return devm_iio_device_register(dev, indio_dev);
}
-EXPORT_SYMBOL_GPL(adxl345_core_probe);
+EXPORT_SYMBOL_NS_GPL(adxl345_core_probe, IIO_ADXL345);
MODULE_AUTHOR("Eva Rachel Retuya <eraretuya@gmail.com>");
MODULE_DESCRIPTION("ADXL345 3-Axis Digital Accelerometer core driver");
diff --git a/drivers/iio/accel/adxl345_i2c.c b/drivers/iio/accel/adxl345_i2c.c
index a431cba216e6..098cd83f95b2 100644
--- a/drivers/iio/accel/adxl345_i2c.c
+++ b/drivers/iio/accel/adxl345_i2c.c
@@ -19,23 +19,15 @@ static const struct regmap_config adxl345_i2c_regmap_config = {
.val_bits = 8,
};
-static int adxl345_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int adxl345_i2c_probe(struct i2c_client *client)
{
struct regmap *regmap;
- if (!id)
- return -ENODEV;
-
regmap = devm_regmap_init_i2c(client, &adxl345_i2c_regmap_config);
- if (IS_ERR(regmap)) {
- dev_err(&client->dev, "Error initializing i2c regmap: %ld\n",
- PTR_ERR(regmap));
- return PTR_ERR(regmap);
- }
+ if (IS_ERR(regmap))
+ return dev_err_probe(&client->dev, PTR_ERR(regmap), "Error initializing regmap\n");
- return adxl345_core_probe(&client->dev, regmap, id->driver_data,
- id->name);
+ return adxl345_core_probe(&client->dev, regmap);
}
static const struct i2c_device_id adxl345_i2c_id[] = {
@@ -43,28 +35,33 @@ static const struct i2c_device_id adxl345_i2c_id[] = {
{ "adxl375", ADXL375 },
{ }
};
-
MODULE_DEVICE_TABLE(i2c, adxl345_i2c_id);
static const struct of_device_id adxl345_of_match[] = {
- { .compatible = "adi,adxl345" },
- { .compatible = "adi,adxl375" },
- { },
+ { .compatible = "adi,adxl345", .data = (const void *)ADXL345 },
+ { .compatible = "adi,adxl375", .data = (const void *)ADXL375 },
+ { }
};
-
MODULE_DEVICE_TABLE(of, adxl345_of_match);
+static const struct acpi_device_id adxl345_acpi_match[] = {
+ { "ADS0345", ADXL345 },
+ { }
+};
+MODULE_DEVICE_TABLE(acpi, adxl345_acpi_match);
+
static struct i2c_driver adxl345_i2c_driver = {
.driver = {
.name = "adxl345_i2c",
.of_match_table = adxl345_of_match,
+ .acpi_match_table = adxl345_acpi_match,
},
- .probe = adxl345_i2c_probe,
+ .probe_new = adxl345_i2c_probe,
.id_table = adxl345_i2c_id,
};
-
module_i2c_driver(adxl345_i2c_driver);
MODULE_AUTHOR("Eva Rachel Retuya <eraretuya@gmail.com>");
MODULE_DESCRIPTION("ADXL345 3-Axis Digital Accelerometer I2C driver");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS(IIO_ADXL345);
diff --git a/drivers/iio/accel/adxl345_spi.c b/drivers/iio/accel/adxl345_spi.c
index ea559ac2e87d..aaade5808657 100644
--- a/drivers/iio/accel/adxl345_spi.c
+++ b/drivers/iio/accel/adxl345_spi.c
@@ -22,24 +22,18 @@ static const struct regmap_config adxl345_spi_regmap_config = {
static int adxl345_spi_probe(struct spi_device *spi)
{
- const struct spi_device_id *id = spi_get_device_id(spi);
struct regmap *regmap;
/* Bail out if max_speed_hz exceeds 5 MHz */
- if (spi->max_speed_hz > ADXL345_MAX_SPI_FREQ_HZ) {
- dev_err(&spi->dev, "SPI CLK, %d Hz exceeds 5 MHz\n",
- spi->max_speed_hz);
- return -EINVAL;
- }
+ if (spi->max_speed_hz > ADXL345_MAX_SPI_FREQ_HZ)
+ return dev_err_probe(&spi->dev, -EINVAL, "SPI CLK, %d Hz exceeds 5 MHz\n",
+ spi->max_speed_hz);
regmap = devm_regmap_init_spi(spi, &adxl345_spi_regmap_config);
- if (IS_ERR(regmap)) {
- dev_err(&spi->dev, "Error initializing spi regmap: %ld\n",
- PTR_ERR(regmap));
- return PTR_ERR(regmap);
- }
+ if (IS_ERR(regmap))
+ return dev_err_probe(&spi->dev, PTR_ERR(regmap), "Error initializing regmap\n");
- return adxl345_core_probe(&spi->dev, regmap, id->driver_data, id->name);
+ return adxl345_core_probe(&spi->dev, regmap);
}
static const struct spi_device_id adxl345_spi_id[] = {
@@ -47,28 +41,33 @@ static const struct spi_device_id adxl345_spi_id[] = {
{ "adxl375", ADXL375 },
{ }
};
-
MODULE_DEVICE_TABLE(spi, adxl345_spi_id);
static const struct of_device_id adxl345_of_match[] = {
- { .compatible = "adi,adxl345" },
- { .compatible = "adi,adxl375" },
- { },
+ { .compatible = "adi,adxl345", .data = (const void *)ADXL345 },
+ { .compatible = "adi,adxl375", .data = (const void *)ADXL375 },
+ { }
};
-
MODULE_DEVICE_TABLE(of, adxl345_of_match);
+static const struct acpi_device_id adxl345_acpi_match[] = {
+ { "ADS0345", ADXL345 },
+ { }
+};
+MODULE_DEVICE_TABLE(acpi, adxl345_acpi_match);
+
static struct spi_driver adxl345_spi_driver = {
.driver = {
.name = "adxl345_spi",
.of_match_table = adxl345_of_match,
+ .acpi_match_table = adxl345_acpi_match,
},
.probe = adxl345_spi_probe,
.id_table = adxl345_spi_id,
};
-
module_spi_driver(adxl345_spi_driver);
MODULE_AUTHOR("Eva Rachel Retuya <eraretuya@gmail.com>");
MODULE_DESCRIPTION("ADXL345 3-Axis Digital Accelerometer SPI driver");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS(IIO_ADXL345);
diff --git a/drivers/iio/accel/adxl355_core.c b/drivers/iio/accel/adxl355_core.c
index 4f485909f459..e9c10c8c32f0 100644
--- a/drivers/iio/accel/adxl355_core.c
+++ b/drivers/iio/accel/adxl355_core.c
@@ -20,6 +20,8 @@
#include <linux/mod_devicetable.h>
#include <linux/of_irq.h>
#include <linux/regmap.h>
+#include <linux/units.h>
+
#include <asm/unaligned.h>
#include "adxl355.h"
@@ -60,9 +62,6 @@
#define ADXL355_PARTID_VAL 0xED
#define ADXL355_RESET_CODE 0x52
-#define MEGA 1000000UL
-#define TERA 1000000000000ULL
-
static const struct regmap_range adxl355_read_reg_range[] = {
regmap_reg_range(ADXL355_DEVID_AD_REG, ADXL355_FIFO_DATA_REG),
regmap_reg_range(ADXL355_OFFSET_X_H_REG, ADXL355_SELF_TEST_REG),
@@ -72,7 +71,7 @@ const struct regmap_access_table adxl355_readable_regs_tbl = {
.yes_ranges = adxl355_read_reg_range,
.n_yes_ranges = ARRAY_SIZE(adxl355_read_reg_range),
};
-EXPORT_SYMBOL_GPL(adxl355_readable_regs_tbl);
+EXPORT_SYMBOL_NS_GPL(adxl355_readable_regs_tbl, IIO_ADXL355);
static const struct regmap_range adxl355_write_reg_range[] = {
regmap_reg_range(ADXL355_OFFSET_X_H_REG, ADXL355_RESET_REG),
@@ -82,7 +81,7 @@ const struct regmap_access_table adxl355_writeable_regs_tbl = {
.yes_ranges = adxl355_write_reg_range,
.n_yes_ranges = ARRAY_SIZE(adxl355_write_reg_range),
};
-EXPORT_SYMBOL_GPL(adxl355_writeable_regs_tbl);
+EXPORT_SYMBOL_NS_GPL(adxl355_writeable_regs_tbl, IIO_ADXL355);
enum adxl355_op_mode {
ADXL355_MEASUREMENT,
@@ -758,7 +757,7 @@ int adxl355_core_probe(struct device *dev, struct regmap *regmap,
return devm_iio_device_register(dev, indio_dev);
}
-EXPORT_SYMBOL_GPL(adxl355_core_probe);
+EXPORT_SYMBOL_NS_GPL(adxl355_core_probe, IIO_ADXL355);
MODULE_AUTHOR("Puranjay Mohan <puranjay12@gmail.com>");
MODULE_DESCRIPTION("ADXL355 3-Axis Digital Accelerometer core driver");
diff --git a/drivers/iio/accel/adxl355_i2c.c b/drivers/iio/accel/adxl355_i2c.c
index 5a987bda9060..f67d57921c81 100644
--- a/drivers/iio/accel/adxl355_i2c.c
+++ b/drivers/iio/accel/adxl355_i2c.c
@@ -60,3 +60,4 @@ module_i2c_driver(adxl355_i2c_driver);
MODULE_AUTHOR("Puranjay Mohan <puranjay12@gmail.com>");
MODULE_DESCRIPTION("ADXL355 3-Axis Digital Accelerometer I2C driver");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS(IIO_ADXL355);
diff --git a/drivers/iio/accel/adxl355_spi.c b/drivers/iio/accel/adxl355_spi.c
index fb225aeb56e3..5fe986ae03f6 100644
--- a/drivers/iio/accel/adxl355_spi.c
+++ b/drivers/iio/accel/adxl355_spi.c
@@ -63,3 +63,4 @@ module_spi_driver(adxl355_spi_driver);
MODULE_AUTHOR("Puranjay Mohan <puranjay12@gmail.com>");
MODULE_DESCRIPTION("ADXL355 3-Axis Digital Accelerometer SPI driver");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS(IIO_ADXL355);
diff --git a/drivers/iio/accel/adxl367.c b/drivers/iio/accel/adxl367.c
new file mode 100644
index 000000000000..62960134ea19
--- /dev/null
+++ b/drivers/iio/accel/adxl367.c
@@ -0,0 +1,1588 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021 Analog Devices, Inc.
+ * Author: Cosmin Tanislav <cosmin.tanislav@analog.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/events.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/kfifo_buf.h>
+#include <linux/iio/sysfs.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mod_devicetable.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <asm/unaligned.h>
+
+#include "adxl367.h"
+
+#define ADXL367_REG_DEVID 0x00
+#define ADXL367_DEVID_AD 0xAD
+
+#define ADXL367_REG_STATUS 0x0B
+#define ADXL367_STATUS_INACT_MASK BIT(5)
+#define ADXL367_STATUS_ACT_MASK BIT(4)
+#define ADXL367_STATUS_FIFO_FULL_MASK BIT(2)
+
+#define ADXL367_FIFO_ENT_H_MASK GENMASK(1, 0)
+
+#define ADXL367_REG_X_DATA_H 0x0E
+#define ADXL367_REG_Y_DATA_H 0x10
+#define ADXL367_REG_Z_DATA_H 0x12
+#define ADXL367_REG_TEMP_DATA_H 0x14
+#define ADXL367_REG_EX_ADC_DATA_H 0x16
+#define ADXL367_DATA_MASK GENMASK(15, 2)
+
+#define ADXL367_TEMP_25C 165
+#define ADXL367_TEMP_PER_C 54
+
+#define ADXL367_VOLTAGE_OFFSET 8192
+#define ADXL367_VOLTAGE_MAX_MV 1000
+#define ADXL367_VOLTAGE_MAX_RAW GENMASK(13, 0)
+
+#define ADXL367_REG_RESET 0x1F
+#define ADXL367_RESET_CODE 0x52
+
+#define ADXL367_REG_THRESH_ACT_H 0x20
+#define ADXL367_REG_THRESH_INACT_H 0x23
+#define ADXL367_THRESH_MAX GENMASK(12, 0)
+#define ADXL367_THRESH_VAL_H_MASK GENMASK(12, 6)
+#define ADXL367_THRESH_H_MASK GENMASK(6, 0)
+#define ADXL367_THRESH_VAL_L_MASK GENMASK(5, 0)
+#define ADXL367_THRESH_L_MASK GENMASK(7, 2)
+
+#define ADXL367_REG_TIME_ACT 0x22
+#define ADXL367_REG_TIME_INACT_H 0x25
+#define ADXL367_TIME_ACT_MAX GENMASK(7, 0)
+#define ADXL367_TIME_INACT_MAX GENMASK(15, 0)
+#define ADXL367_TIME_INACT_VAL_H_MASK GENMASK(15, 8)
+#define ADXL367_TIME_INACT_H_MASK GENMASK(7, 0)
+#define ADXL367_TIME_INACT_VAL_L_MASK GENMASK(7, 0)
+#define ADXL367_TIME_INACT_L_MASK GENMASK(7, 0)
+
+#define ADXL367_REG_ACT_INACT_CTL 0x27
+#define ADXL367_ACT_EN_MASK GENMASK(1, 0)
+#define ADXL367_ACT_LINKLOOP_MASK GENMASK(5, 4)
+
+#define ADXL367_REG_FIFO_CTL 0x28
+#define ADXL367_FIFO_CTL_FORMAT_MASK GENMASK(6, 3)
+#define ADXL367_FIFO_CTL_MODE_MASK GENMASK(1, 0)
+
+#define ADXL367_REG_FIFO_SAMPLES 0x29
+#define ADXL367_FIFO_SIZE 512
+#define ADXL367_FIFO_MAX_WATERMARK 511
+
+#define ADXL367_SAMPLES_VAL_H_MASK BIT(8)
+#define ADXL367_SAMPLES_H_MASK BIT(2)
+#define ADXL367_SAMPLES_VAL_L_MASK GENMASK(7, 0)
+#define ADXL367_SAMPLES_L_MASK GENMASK(7, 0)
+
+#define ADXL367_REG_INT1_MAP 0x2A
+#define ADXL367_INT_INACT_MASK BIT(5)
+#define ADXL367_INT_ACT_MASK BIT(4)
+#define ADXL367_INT_FIFO_WATERMARK_MASK BIT(2)
+
+#define ADXL367_REG_FILTER_CTL 0x2C
+#define ADXL367_FILTER_CTL_RANGE_MASK GENMASK(7, 6)
+#define ADXL367_2G_RANGE_1G 4095
+#define ADXL367_2G_RANGE_100MG 409
+#define ADXL367_FILTER_CTL_ODR_MASK GENMASK(2, 0)
+
+#define ADXL367_REG_POWER_CTL 0x2D
+#define ADXL367_POWER_CTL_MODE_MASK GENMASK(1, 0)
+
+#define ADXL367_REG_ADC_CTL 0x3C
+#define ADXL367_REG_TEMP_CTL 0x3D
+#define ADXL367_ADC_EN_MASK BIT(0)
+
+enum adxl367_range {
+ ADXL367_2G_RANGE,
+ ADXL367_4G_RANGE,
+ ADXL367_8G_RANGE,
+};
+
+enum adxl367_fifo_mode {
+ ADXL367_FIFO_MODE_DISABLED = 0b00,
+ ADXL367_FIFO_MODE_STREAM = 0b10,
+};
+
+enum adxl367_fifo_format {
+ ADXL367_FIFO_FORMAT_XYZ,
+ ADXL367_FIFO_FORMAT_X,
+ ADXL367_FIFO_FORMAT_Y,
+ ADXL367_FIFO_FORMAT_Z,
+ ADXL367_FIFO_FORMAT_XYZT,
+ ADXL367_FIFO_FORMAT_XT,
+ ADXL367_FIFO_FORMAT_YT,
+ ADXL367_FIFO_FORMAT_ZT,
+ ADXL367_FIFO_FORMAT_XYZA,
+ ADXL367_FIFO_FORMAT_XA,
+ ADXL367_FIFO_FORMAT_YA,
+ ADXL367_FIFO_FORMAT_ZA,
+};
+
+enum adxl367_op_mode {
+ ADXL367_OP_STANDBY = 0b00,
+ ADXL367_OP_MEASURE = 0b10,
+};
+
+enum adxl367_act_proc_mode {
+ ADXL367_LOOPED = 0b11,
+};
+
+enum adxl367_act_en_mode {
+ ADXL367_ACT_DISABLED = 0b00,
+ ADCL367_ACT_REF_ENABLED = 0b11,
+};
+
+enum adxl367_activity_type {
+ ADXL367_ACTIVITY,
+ ADXL367_INACTIVITY,
+};
+
+enum adxl367_odr {
+ ADXL367_ODR_12P5HZ,
+ ADXL367_ODR_25HZ,
+ ADXL367_ODR_50HZ,
+ ADXL367_ODR_100HZ,
+ ADXL367_ODR_200HZ,
+ ADXL367_ODR_400HZ,
+};
+
+struct adxl367_state {
+ const struct adxl367_ops *ops;
+ void *context;
+
+ struct device *dev;
+ struct regmap *regmap;
+
+ struct regulator_bulk_data regulators[2];
+
+ /*
+ * Synchronize access to members of driver state, and ensure atomicity
+ * of consecutive regmap operations.
+ */
+ struct mutex lock;
+
+ enum adxl367_odr odr;
+ enum adxl367_range range;
+
+ unsigned int act_threshold;
+ unsigned int act_time_ms;
+ unsigned int inact_threshold;
+ unsigned int inact_time_ms;
+
+ unsigned int fifo_set_size;
+ unsigned int fifo_watermark;
+
+ __be16 fifo_buf[ADXL367_FIFO_SIZE] ____cacheline_aligned;
+ __be16 sample_buf;
+ u8 act_threshold_buf[2];
+ u8 inact_time_buf[2];
+ u8 status_buf[3];
+};
+
+static const unsigned int adxl367_threshold_h_reg_tbl[] = {
+ [ADXL367_ACTIVITY] = ADXL367_REG_THRESH_ACT_H,
+ [ADXL367_INACTIVITY] = ADXL367_REG_THRESH_INACT_H,
+};
+
+static const unsigned int adxl367_act_en_shift_tbl[] = {
+ [ADXL367_ACTIVITY] = 0,
+ [ADXL367_INACTIVITY] = 2,
+};
+
+static const unsigned int adxl367_act_int_mask_tbl[] = {
+ [ADXL367_ACTIVITY] = ADXL367_INT_ACT_MASK,
+ [ADXL367_INACTIVITY] = ADXL367_INT_INACT_MASK,
+};
+
+static const int adxl367_samp_freq_tbl[][2] = {
+ [ADXL367_ODR_12P5HZ] = {12, 500000},
+ [ADXL367_ODR_25HZ] = {25, 0},
+ [ADXL367_ODR_50HZ] = {50, 0},
+ [ADXL367_ODR_100HZ] = {100, 0},
+ [ADXL367_ODR_200HZ] = {200, 0},
+ [ADXL367_ODR_400HZ] = {400, 0},
+};
+
+/* (g * 2) * 9.80665 * 1000000 / (2^14 - 1) */
+static const int adxl367_range_scale_tbl[][2] = {
+ [ADXL367_2G_RANGE] = {0, 2394347},
+ [ADXL367_4G_RANGE] = {0, 4788695},
+ [ADXL367_8G_RANGE] = {0, 9577391},
+};
+
+static const int adxl367_range_scale_factor_tbl[] = {
+ [ADXL367_2G_RANGE] = 1,
+ [ADXL367_4G_RANGE] = 2,
+ [ADXL367_8G_RANGE] = 4,
+};
+
+enum {
+ ADXL367_X_CHANNEL_INDEX,
+ ADXL367_Y_CHANNEL_INDEX,
+ ADXL367_Z_CHANNEL_INDEX,
+ ADXL367_TEMP_CHANNEL_INDEX,
+ ADXL367_EX_ADC_CHANNEL_INDEX
+};
+
+#define ADXL367_X_CHANNEL_MASK BIT(ADXL367_X_CHANNEL_INDEX)
+#define ADXL367_Y_CHANNEL_MASK BIT(ADXL367_Y_CHANNEL_INDEX)
+#define ADXL367_Z_CHANNEL_MASK BIT(ADXL367_Z_CHANNEL_INDEX)
+#define ADXL367_TEMP_CHANNEL_MASK BIT(ADXL367_TEMP_CHANNEL_INDEX)
+#define ADXL367_EX_ADC_CHANNEL_MASK BIT(ADXL367_EX_ADC_CHANNEL_INDEX)
+
+static const enum adxl367_fifo_format adxl367_fifo_formats[] = {
+ ADXL367_FIFO_FORMAT_X,
+ ADXL367_FIFO_FORMAT_Y,
+ ADXL367_FIFO_FORMAT_Z,
+ ADXL367_FIFO_FORMAT_XT,
+ ADXL367_FIFO_FORMAT_YT,
+ ADXL367_FIFO_FORMAT_ZT,
+ ADXL367_FIFO_FORMAT_XA,
+ ADXL367_FIFO_FORMAT_YA,
+ ADXL367_FIFO_FORMAT_ZA,
+ ADXL367_FIFO_FORMAT_XYZ,
+ ADXL367_FIFO_FORMAT_XYZT,
+ ADXL367_FIFO_FORMAT_XYZA,
+};
+
+static const unsigned long adxl367_channel_masks[] = {
+ ADXL367_X_CHANNEL_MASK,
+ ADXL367_Y_CHANNEL_MASK,
+ ADXL367_Z_CHANNEL_MASK,
+ ADXL367_X_CHANNEL_MASK | ADXL367_TEMP_CHANNEL_MASK,
+ ADXL367_Y_CHANNEL_MASK | ADXL367_TEMP_CHANNEL_MASK,
+ ADXL367_Z_CHANNEL_MASK | ADXL367_TEMP_CHANNEL_MASK,
+ ADXL367_X_CHANNEL_MASK | ADXL367_EX_ADC_CHANNEL_MASK,
+ ADXL367_Y_CHANNEL_MASK | ADXL367_EX_ADC_CHANNEL_MASK,
+ ADXL367_Z_CHANNEL_MASK | ADXL367_EX_ADC_CHANNEL_MASK,
+ ADXL367_X_CHANNEL_MASK | ADXL367_Y_CHANNEL_MASK | ADXL367_Z_CHANNEL_MASK,
+ ADXL367_X_CHANNEL_MASK | ADXL367_Y_CHANNEL_MASK | ADXL367_Z_CHANNEL_MASK |
+ ADXL367_TEMP_CHANNEL_MASK,
+ ADXL367_X_CHANNEL_MASK | ADXL367_Y_CHANNEL_MASK | ADXL367_Z_CHANNEL_MASK |
+ ADXL367_EX_ADC_CHANNEL_MASK,
+ 0,
+};
+
+static int adxl367_set_measure_en(struct adxl367_state *st, bool en)
+{
+ enum adxl367_op_mode op_mode = en ? ADXL367_OP_MEASURE
+ : ADXL367_OP_STANDBY;
+ int ret;
+
+ ret = regmap_update_bits(st->regmap, ADXL367_REG_POWER_CTL,
+ ADXL367_POWER_CTL_MODE_MASK,
+ FIELD_PREP(ADXL367_POWER_CTL_MODE_MASK,
+ op_mode));
+ if (ret)
+ return ret;
+
+ /*
+ * Wait for acceleration output to settle after entering
+ * measure mode.
+ */
+ if (en)
+ msleep(100);
+
+ return 0;
+}
+
+static void adxl367_scale_act_thresholds(struct adxl367_state *st,
+ enum adxl367_range old_range,
+ enum adxl367_range new_range)
+{
+ st->act_threshold = st->act_threshold
+ * adxl367_range_scale_factor_tbl[old_range]
+ / adxl367_range_scale_factor_tbl[new_range];
+ st->inact_threshold = st->inact_threshold
+ * adxl367_range_scale_factor_tbl[old_range]
+ / adxl367_range_scale_factor_tbl[new_range];
+}
+
+static int _adxl367_set_act_threshold(struct adxl367_state *st,
+ enum adxl367_activity_type act,
+ unsigned int threshold)
+{
+ u8 reg = adxl367_threshold_h_reg_tbl[act];
+ int ret;
+
+ if (threshold > ADXL367_THRESH_MAX)
+ return -EINVAL;
+
+ st->act_threshold_buf[0] = FIELD_PREP(ADXL367_THRESH_H_MASK,
+ FIELD_GET(ADXL367_THRESH_VAL_H_MASK,
+ threshold));
+ st->act_threshold_buf[1] = FIELD_PREP(ADXL367_THRESH_L_MASK,
+ FIELD_GET(ADXL367_THRESH_VAL_L_MASK,
+ threshold));
+
+ ret = regmap_bulk_write(st->regmap, reg, st->act_threshold_buf,
+ sizeof(st->act_threshold_buf));
+ if (ret)
+ return ret;
+
+ if (act == ADXL367_ACTIVITY)
+ st->act_threshold = threshold;
+ else
+ st->inact_threshold = threshold;
+
+ return 0;
+}
+
+static int adxl367_set_act_threshold(struct adxl367_state *st,
+ enum adxl367_activity_type act,
+ unsigned int threshold)
+{
+ int ret;
+
+ mutex_lock(&st->lock);
+
+ ret = adxl367_set_measure_en(st, false);
+ if (ret)
+ goto out;
+
+ ret = _adxl367_set_act_threshold(st, act, threshold);
+ if (ret)
+ goto out;
+
+ ret = adxl367_set_measure_en(st, true);
+
+out:
+ mutex_unlock(&st->lock);
+
+ return ret;
+}
+
+static int adxl367_set_act_proc_mode(struct adxl367_state *st,
+ enum adxl367_act_proc_mode mode)
+{
+ return regmap_update_bits(st->regmap, ADXL367_REG_ACT_INACT_CTL,
+ ADXL367_ACT_LINKLOOP_MASK,
+ FIELD_PREP(ADXL367_ACT_LINKLOOP_MASK,
+ mode));
+}
+
+static int adxl367_set_act_interrupt_en(struct adxl367_state *st,
+ enum adxl367_activity_type act,
+ bool en)
+{
+ unsigned int mask = adxl367_act_int_mask_tbl[act];
+
+ return regmap_update_bits(st->regmap, ADXL367_REG_INT1_MAP,
+ mask, en ? mask : 0);
+}
+
+static int adxl367_get_act_interrupt_en(struct adxl367_state *st,
+ enum adxl367_activity_type act,
+ bool *en)
+{
+ unsigned int mask = adxl367_act_int_mask_tbl[act];
+ unsigned int val;
+ int ret;
+
+ ret = regmap_read(st->regmap, ADXL367_REG_INT1_MAP, &val);
+ if (ret)
+ return ret;
+
+ *en = !!(val & mask);
+
+ return 0;
+}
+
+static int adxl367_set_act_en(struct adxl367_state *st,
+ enum adxl367_activity_type act,
+ enum adxl367_act_en_mode en)
+{
+ unsigned int ctl_shift = adxl367_act_en_shift_tbl[act];
+
+ return regmap_update_bits(st->regmap, ADXL367_REG_ACT_INACT_CTL,
+ ADXL367_ACT_EN_MASK << ctl_shift,
+ en << ctl_shift);
+}
+
+static int adxl367_set_fifo_watermark_interrupt_en(struct adxl367_state *st,
+ bool en)
+{
+ return regmap_update_bits(st->regmap, ADXL367_REG_INT1_MAP,
+ ADXL367_INT_FIFO_WATERMARK_MASK,
+ en ? ADXL367_INT_FIFO_WATERMARK_MASK : 0);
+}
+
+static int adxl367_get_fifo_mode(struct adxl367_state *st,
+ enum adxl367_fifo_mode *fifo_mode)
+{
+ unsigned int val;
+ int ret;
+
+ ret = regmap_read(st->regmap, ADXL367_REG_FIFO_CTL, &val);
+ if (ret)
+ return ret;
+
+ *fifo_mode = FIELD_GET(ADXL367_FIFO_CTL_MODE_MASK, val);
+
+ return 0;
+}
+
+static int adxl367_set_fifo_mode(struct adxl367_state *st,
+ enum adxl367_fifo_mode fifo_mode)
+{
+ return regmap_update_bits(st->regmap, ADXL367_REG_FIFO_CTL,
+ ADXL367_FIFO_CTL_MODE_MASK,
+ FIELD_PREP(ADXL367_FIFO_CTL_MODE_MASK,
+ fifo_mode));
+}
+
+static int adxl367_set_fifo_format(struct adxl367_state *st,
+ enum adxl367_fifo_format fifo_format)
+{
+ return regmap_update_bits(st->regmap, ADXL367_REG_FIFO_CTL,
+ ADXL367_FIFO_CTL_FORMAT_MASK,
+ FIELD_PREP(ADXL367_FIFO_CTL_FORMAT_MASK,
+ fifo_format));
+}
+
+static int adxl367_set_fifo_samples(struct adxl367_state *st,
+ unsigned int fifo_watermark,
+ unsigned int fifo_set_size)
+{
+ unsigned int fifo_samples = fifo_watermark * fifo_set_size;
+ unsigned int fifo_samples_h, fifo_samples_l;
+ int ret;
+
+ if (fifo_samples > ADXL367_FIFO_MAX_WATERMARK)
+ fifo_samples = ADXL367_FIFO_MAX_WATERMARK;
+
+ if (fifo_set_size == 0)
+ return 0;
+
+ fifo_samples /= fifo_set_size;
+
+ fifo_samples_h = FIELD_PREP(ADXL367_SAMPLES_H_MASK,
+ FIELD_GET(ADXL367_SAMPLES_VAL_H_MASK,
+ fifo_samples));
+ fifo_samples_l = FIELD_PREP(ADXL367_SAMPLES_L_MASK,
+ FIELD_GET(ADXL367_SAMPLES_VAL_L_MASK,
+ fifo_samples));
+
+ ret = regmap_update_bits(st->regmap, ADXL367_REG_FIFO_CTL,
+ ADXL367_SAMPLES_H_MASK, fifo_samples_h);
+ if (ret)
+ return ret;
+
+ return regmap_update_bits(st->regmap, ADXL367_REG_FIFO_SAMPLES,
+ ADXL367_SAMPLES_L_MASK, fifo_samples_l);
+}
+
+static int adxl367_set_fifo_set_size(struct adxl367_state *st,
+ unsigned int fifo_set_size)
+{
+ int ret;
+
+ ret = adxl367_set_fifo_samples(st, st->fifo_watermark, fifo_set_size);
+ if (ret)
+ return ret;
+
+ st->fifo_set_size = fifo_set_size;
+
+ return 0;
+}
+
+static int adxl367_set_fifo_watermark(struct adxl367_state *st,
+ unsigned int fifo_watermark)
+{
+ int ret;
+
+ ret = adxl367_set_fifo_samples(st, fifo_watermark, st->fifo_set_size);
+ if (ret)
+ return ret;
+
+ st->fifo_watermark = fifo_watermark;
+
+ return 0;
+}
+
+static int adxl367_set_range(struct iio_dev *indio_dev,
+ enum adxl367_range range)
+{
+ struct adxl367_state *st = iio_priv(indio_dev);
+ int ret;
+
+ ret = iio_device_claim_direct_mode(indio_dev);
+ if (ret)
+ return ret;
+
+ mutex_lock(&st->lock);
+
+ ret = adxl367_set_measure_en(st, false);
+ if (ret)
+ goto out;
+
+ ret = regmap_update_bits(st->regmap, ADXL367_REG_FILTER_CTL,
+ ADXL367_FILTER_CTL_RANGE_MASK,
+ FIELD_PREP(ADXL367_FILTER_CTL_RANGE_MASK,
+ range));
+ if (ret)
+ goto out;
+
+ adxl367_scale_act_thresholds(st, st->range, range);
+
+ /* Activity thresholds depend on range */
+ ret = _adxl367_set_act_threshold(st, ADXL367_ACTIVITY,
+ st->act_threshold);
+ if (ret)
+ goto out;
+
+ ret = _adxl367_set_act_threshold(st, ADXL367_INACTIVITY,
+ st->inact_threshold);
+ if (ret)
+ goto out;
+
+ ret = adxl367_set_measure_en(st, true);
+ if (ret)
+ goto out;
+
+ st->range = range;
+
+out:
+ mutex_unlock(&st->lock);
+
+ iio_device_release_direct_mode(indio_dev);
+
+ return ret;
+}
+
+static int adxl367_time_ms_to_samples(struct adxl367_state *st, unsigned int ms)
+{
+ int freq_hz = adxl367_samp_freq_tbl[st->odr][0];
+ int freq_microhz = adxl367_samp_freq_tbl[st->odr][1];
+ /* Scale to decihertz to prevent precision loss in 12.5Hz case. */
+ int freq_dhz = freq_hz * 10 + freq_microhz / 100000;
+
+ return DIV_ROUND_CLOSEST(ms * freq_dhz, 10000);
+}
+
+static int _adxl367_set_act_time_ms(struct adxl367_state *st, unsigned int ms)
+{
+ unsigned int val = adxl367_time_ms_to_samples(st, ms);
+ int ret;
+
+ if (val > ADXL367_TIME_ACT_MAX)
+ val = ADXL367_TIME_ACT_MAX;
+
+ ret = regmap_write(st->regmap, ADXL367_REG_TIME_ACT, val);
+ if (ret)
+ return ret;
+
+ st->act_time_ms = ms;
+
+ return 0;
+}
+
+static int _adxl367_set_inact_time_ms(struct adxl367_state *st, unsigned int ms)
+{
+ unsigned int val = adxl367_time_ms_to_samples(st, ms);
+ int ret;
+
+ if (val > ADXL367_TIME_INACT_MAX)
+ val = ADXL367_TIME_INACT_MAX;
+
+ st->inact_time_buf[0] = FIELD_PREP(ADXL367_TIME_INACT_H_MASK,
+ FIELD_GET(ADXL367_TIME_INACT_VAL_H_MASK,
+ val));
+ st->inact_time_buf[1] = FIELD_PREP(ADXL367_TIME_INACT_L_MASK,
+ FIELD_GET(ADXL367_TIME_INACT_VAL_L_MASK,
+ val));
+
+ ret = regmap_bulk_write(st->regmap, ADXL367_REG_TIME_INACT_H,
+ st->inact_time_buf, sizeof(st->inact_time_buf));
+ if (ret)
+ return ret;
+
+ st->inact_time_ms = ms;
+
+ return 0;
+}
+
+static int adxl367_set_act_time_ms(struct adxl367_state *st,
+ enum adxl367_activity_type act,
+ unsigned int ms)
+{
+ int ret;
+
+ mutex_lock(&st->lock);
+
+ ret = adxl367_set_measure_en(st, false);
+ if (ret)
+ goto out;
+
+ if (act == ADXL367_ACTIVITY)
+ ret = _adxl367_set_act_time_ms(st, ms);
+ else
+ ret = _adxl367_set_inact_time_ms(st, ms);
+
+ if (ret)
+ goto out;
+
+ ret = adxl367_set_measure_en(st, true);
+
+out:
+ mutex_unlock(&st->lock);
+
+ return ret;
+}
+
+static int _adxl367_set_odr(struct adxl367_state *st, enum adxl367_odr odr)
+{
+ int ret;
+
+ ret = regmap_update_bits(st->regmap, ADXL367_REG_FILTER_CTL,
+ ADXL367_FILTER_CTL_ODR_MASK,
+ FIELD_PREP(ADXL367_FILTER_CTL_ODR_MASK,
+ odr));
+ if (ret)
+ return ret;
+
+ /* Activity timers depend on ODR */
+ ret = _adxl367_set_act_time_ms(st, st->act_time_ms);
+ if (ret)
+ return ret;
+
+ ret = _adxl367_set_inact_time_ms(st, st->inact_time_ms);
+ if (ret)
+ return ret;
+
+ st->odr = odr;
+
+ return 0;
+}
+
+static int adxl367_set_odr(struct iio_dev *indio_dev, enum adxl367_odr odr)
+{
+ struct adxl367_state *st = iio_priv(indio_dev);
+ int ret;
+
+ ret = iio_device_claim_direct_mode(indio_dev);
+ if (ret)
+ return ret;
+
+ mutex_lock(&st->lock);
+
+ ret = adxl367_set_measure_en(st, false);
+ if (ret)
+ goto out;
+
+ ret = _adxl367_set_odr(st, odr);
+ if (ret)
+ goto out;
+
+ ret = adxl367_set_measure_en(st, true);
+
+out:
+ mutex_unlock(&st->lock);
+
+ iio_device_release_direct_mode(indio_dev);
+
+ return ret;
+}
+
+static int adxl367_set_temp_adc_en(struct adxl367_state *st, unsigned int reg,
+ bool en)
+{
+ return regmap_update_bits(st->regmap, reg, ADXL367_ADC_EN_MASK,
+ en ? ADXL367_ADC_EN_MASK : 0);
+}
+
+static int adxl367_set_temp_adc_reg_en(struct adxl367_state *st,
+ unsigned int reg, bool en)
+{
+ int ret;
+
+ switch (reg) {
+ case ADXL367_REG_TEMP_DATA_H:
+ ret = adxl367_set_temp_adc_en(st, ADXL367_REG_TEMP_CTL, en);
+ break;
+ case ADXL367_REG_EX_ADC_DATA_H:
+ ret = adxl367_set_temp_adc_en(st, ADXL367_REG_ADC_CTL, en);
+ break;
+ default:
+ return 0;
+ }
+
+ if (ret)
+ return ret;
+
+ if (en)
+ msleep(100);
+
+ return 0;
+}
+
+static int adxl367_set_temp_adc_mask_en(struct adxl367_state *st,
+ const unsigned long *active_scan_mask,
+ bool en)
+{
+ if (*active_scan_mask & ADXL367_TEMP_CHANNEL_MASK)
+ return adxl367_set_temp_adc_en(st, ADXL367_REG_TEMP_CTL, en);
+ else if (*active_scan_mask & ADXL367_EX_ADC_CHANNEL_MASK)
+ return adxl367_set_temp_adc_en(st, ADXL367_REG_ADC_CTL, en);
+
+ return 0;
+}
+
+static int adxl367_find_odr(struct adxl367_state *st, int val, int val2,
+ enum adxl367_odr *odr)
+{
+ size_t size = ARRAY_SIZE(adxl367_samp_freq_tbl);
+ int i;
+
+ for (i = 0; i < size; i++)
+ if (val == adxl367_samp_freq_tbl[i][0] &&
+ val2 == adxl367_samp_freq_tbl[i][1])
+ break;
+
+ if (i == size)
+ return -EINVAL;
+
+ *odr = i;
+
+ return 0;
+}
+
+static int adxl367_find_range(struct adxl367_state *st, int val, int val2,
+ enum adxl367_range *range)
+{
+ size_t size = ARRAY_SIZE(adxl367_range_scale_tbl);
+ int i;
+
+ for (i = 0; i < size; i++)
+ if (val == adxl367_range_scale_tbl[i][0] &&
+ val2 == adxl367_range_scale_tbl[i][1])
+ break;
+
+ if (i == size)
+ return -EINVAL;
+
+ *range = i;
+
+ return 0;
+}
+
+static int adxl367_read_sample(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val)
+{
+ struct adxl367_state *st = iio_priv(indio_dev);
+ u16 sample;
+ int ret;
+
+ ret = iio_device_claim_direct_mode(indio_dev);
+ if (ret)
+ return ret;
+
+ mutex_lock(&st->lock);
+
+ ret = adxl367_set_temp_adc_reg_en(st, chan->address, true);
+ if (ret)
+ goto out;
+
+ ret = regmap_bulk_read(st->regmap, chan->address, &st->sample_buf,
+ sizeof(st->sample_buf));
+ if (ret)
+ goto out;
+
+ sample = FIELD_GET(ADXL367_DATA_MASK, be16_to_cpu(st->sample_buf));
+ *val = sign_extend32(sample, chan->scan_type.realbits - 1);
+
+ ret = adxl367_set_temp_adc_reg_en(st, chan->address, false);
+
+out:
+ mutex_unlock(&st->lock);
+
+ iio_device_release_direct_mode(indio_dev);
+
+ return ret ?: IIO_VAL_INT;
+}
+
+static int adxl367_get_status(struct adxl367_state *st, u8 *status,
+ u16 *fifo_entries)
+{
+ int ret;
+
+ /* Read STATUS, FIFO_ENT_L and FIFO_ENT_H */
+ ret = regmap_bulk_read(st->regmap, ADXL367_REG_STATUS,
+ st->status_buf, sizeof(st->status_buf));
+ if (ret)
+ return ret;
+
+ st->status_buf[2] &= ADXL367_FIFO_ENT_H_MASK;
+
+ *status = st->status_buf[0];
+ *fifo_entries = get_unaligned_le16(&st->status_buf[1]);
+
+ return 0;
+}
+
+static bool adxl367_push_event(struct iio_dev *indio_dev, u8 status)
+{
+ unsigned int ev_dir;
+
+ if (FIELD_GET(ADXL367_STATUS_ACT_MASK, status))
+ ev_dir = IIO_EV_DIR_RISING;
+ else if (FIELD_GET(ADXL367_STATUS_INACT_MASK, status))
+ ev_dir = IIO_EV_DIR_FALLING;
+ else
+ return false;
+
+ iio_push_event(indio_dev,
+ IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, IIO_MOD_X_OR_Y_OR_Z,
+ IIO_EV_TYPE_THRESH, ev_dir),
+ iio_get_time_ns(indio_dev));
+
+ return true;
+}
+
+static bool adxl367_push_fifo_data(struct iio_dev *indio_dev, u8 status,
+ u16 fifo_entries)
+{
+ struct adxl367_state *st = iio_priv(indio_dev);
+ int ret;
+ int i;
+
+ if (!FIELD_GET(ADXL367_STATUS_FIFO_FULL_MASK, status))
+ return false;
+
+ fifo_entries -= fifo_entries % st->fifo_set_size;
+
+ ret = st->ops->read_fifo(st->context, st->fifo_buf, fifo_entries);
+ if (ret) {
+ dev_err(st->dev, "Failed to read FIFO: %d\n", ret);
+ return true;
+ }
+
+ for (i = 0; i < fifo_entries; i += st->fifo_set_size)
+ iio_push_to_buffers(indio_dev, &st->fifo_buf[i]);
+
+ return true;
+}
+
+static irqreturn_t adxl367_irq_handler(int irq, void *private)
+{
+ struct iio_dev *indio_dev = private;
+ struct adxl367_state *st = iio_priv(indio_dev);
+ u16 fifo_entries;
+ bool handled;
+ u8 status;
+ int ret;
+
+ ret = adxl367_get_status(st, &status, &fifo_entries);
+ if (ret)
+ return IRQ_NONE;
+
+ handled = adxl367_push_event(indio_dev, status);
+ handled |= adxl367_push_fifo_data(indio_dev, status, fifo_entries);
+
+ return handled ? IRQ_HANDLED : IRQ_NONE;
+}
+
+static int adxl367_reg_access(struct iio_dev *indio_dev,
+ unsigned int reg,
+ unsigned int writeval,
+ unsigned int *readval)
+{
+ struct adxl367_state *st = iio_priv(indio_dev);
+
+ if (readval)
+ return regmap_read(st->regmap, reg, readval);
+ else
+ return regmap_write(st->regmap, reg, writeval);
+}
+
+static int adxl367_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long info)
+{
+ struct adxl367_state *st = iio_priv(indio_dev);
+
+ switch (info) {
+ case IIO_CHAN_INFO_RAW:
+ return adxl367_read_sample(indio_dev, chan, val);
+ case IIO_CHAN_INFO_SCALE:
+ switch (chan->type) {
+ case IIO_ACCEL:
+ mutex_lock(&st->lock);
+ *val = adxl367_range_scale_tbl[st->range][0];
+ *val2 = adxl367_range_scale_tbl[st->range][1];
+ mutex_unlock(&st->lock);
+ return IIO_VAL_INT_PLUS_NANO;
+ case IIO_TEMP:
+ *val = 1000;
+ *val2 = ADXL367_TEMP_PER_C;
+ return IIO_VAL_FRACTIONAL;
+ case IIO_VOLTAGE:
+ *val = ADXL367_VOLTAGE_MAX_MV;
+ *val2 = ADXL367_VOLTAGE_MAX_RAW;
+ return IIO_VAL_FRACTIONAL;
+ default:
+ return -EINVAL;
+ }
+ case IIO_CHAN_INFO_OFFSET:
+ switch (chan->type) {
+ case IIO_TEMP:
+ *val = 25 * ADXL367_TEMP_PER_C - ADXL367_TEMP_25C;
+ return IIO_VAL_INT;
+ case IIO_VOLTAGE:
+ *val = ADXL367_VOLTAGE_OFFSET;
+ return IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ mutex_lock(&st->lock);
+ *val = adxl367_samp_freq_tbl[st->odr][0];
+ *val2 = adxl367_samp_freq_tbl[st->odr][1];
+ mutex_unlock(&st->lock);
+ return IIO_VAL_INT_PLUS_MICRO;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int adxl367_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val, int val2, long info)
+{
+ struct adxl367_state *st = iio_priv(indio_dev);
+ int ret;
+
+ switch (info) {
+ case IIO_CHAN_INFO_SAMP_FREQ: {
+ enum adxl367_odr odr;
+
+ ret = adxl367_find_odr(st, val, val2, &odr);
+ if (ret)
+ return ret;
+
+ return adxl367_set_odr(indio_dev, odr);
+ }
+ case IIO_CHAN_INFO_SCALE: {
+ enum adxl367_range range;
+
+ ret = adxl367_find_range(st, val, val2, &range);
+ if (ret)
+ return ret;
+
+ return adxl367_set_range(indio_dev, range);
+ }
+ default:
+ return -EINVAL;
+ }
+}
+
+static int adxl367_write_raw_get_fmt(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ long info)
+{
+ switch (info) {
+ case IIO_CHAN_INFO_SCALE:
+ if (chan->type != IIO_ACCEL)
+ return -EINVAL;
+
+ return IIO_VAL_INT_PLUS_NANO;
+ default:
+ return IIO_VAL_INT_PLUS_MICRO;
+ }
+}
+
+static int adxl367_read_avail(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ const int **vals, int *type, int *length,
+ long info)
+{
+ switch (info) {
+ case IIO_CHAN_INFO_SCALE:
+ if (chan->type != IIO_ACCEL)
+ return -EINVAL;
+
+ *vals = (int *)adxl367_range_scale_tbl;
+ *type = IIO_VAL_INT_PLUS_NANO;
+ *length = ARRAY_SIZE(adxl367_range_scale_tbl) * 2;
+ return IIO_AVAIL_LIST;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ *vals = (int *)adxl367_samp_freq_tbl;
+ *type = IIO_VAL_INT_PLUS_MICRO;
+ *length = ARRAY_SIZE(adxl367_samp_freq_tbl) * 2;
+ return IIO_AVAIL_LIST;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int adxl367_read_event_value(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ enum iio_event_type type,
+ enum iio_event_direction dir,
+ enum iio_event_info info,
+ int *val, int *val2)
+{
+ struct adxl367_state *st = iio_priv(indio_dev);
+
+ switch (info) {
+ case IIO_EV_INFO_VALUE: {
+ switch (dir) {
+ case IIO_EV_DIR_RISING:
+ mutex_lock(&st->lock);
+ *val = st->act_threshold;
+ mutex_unlock(&st->lock);
+ return IIO_VAL_INT;
+ case IIO_EV_DIR_FALLING:
+ mutex_lock(&st->lock);
+ *val = st->inact_threshold;
+ mutex_unlock(&st->lock);
+ return IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
+ }
+ case IIO_EV_INFO_PERIOD:
+ switch (dir) {
+ case IIO_EV_DIR_RISING:
+ mutex_lock(&st->lock);
+ *val = st->act_time_ms;
+ mutex_unlock(&st->lock);
+ *val2 = 1000;
+ return IIO_VAL_FRACTIONAL;
+ case IIO_EV_DIR_FALLING:
+ mutex_lock(&st->lock);
+ *val = st->inact_time_ms;
+ mutex_unlock(&st->lock);
+ *val2 = 1000;
+ return IIO_VAL_FRACTIONAL;
+ default:
+ return -EINVAL;
+ }
+ default:
+ return -EINVAL;
+ }
+}
+
+static int adxl367_write_event_value(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ enum iio_event_type type,
+ enum iio_event_direction dir,
+ enum iio_event_info info,
+ int val, int val2)
+{
+ struct adxl367_state *st = iio_priv(indio_dev);
+
+ switch (info) {
+ case IIO_EV_INFO_VALUE:
+ if (val < 0)
+ return -EINVAL;
+
+ switch (dir) {
+ case IIO_EV_DIR_RISING:
+ return adxl367_set_act_threshold(st, ADXL367_ACTIVITY, val);
+ case IIO_EV_DIR_FALLING:
+ return adxl367_set_act_threshold(st, ADXL367_INACTIVITY, val);
+ default:
+ return -EINVAL;
+ }
+ case IIO_EV_INFO_PERIOD:
+ if (val < 0)
+ return -EINVAL;
+
+ val = val * 1000 + DIV_ROUND_UP(val2, 1000);
+ switch (dir) {
+ case IIO_EV_DIR_RISING:
+ return adxl367_set_act_time_ms(st, ADXL367_ACTIVITY, val);
+ case IIO_EV_DIR_FALLING:
+ return adxl367_set_act_time_ms(st, ADXL367_INACTIVITY, val);
+ default:
+ return -EINVAL;
+ }
+ default:
+ return -EINVAL;
+ }
+}
+
+static int adxl367_read_event_config(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ enum iio_event_type type,
+ enum iio_event_direction dir)
+{
+ struct adxl367_state *st = iio_priv(indio_dev);
+ bool en;
+ int ret;
+
+ switch (dir) {
+ case IIO_EV_DIR_RISING:
+ ret = adxl367_get_act_interrupt_en(st, ADXL367_ACTIVITY, &en);
+ return ret ?: en;
+ case IIO_EV_DIR_FALLING:
+ ret = adxl367_get_act_interrupt_en(st, ADXL367_INACTIVITY, &en);
+ return ret ?: en;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int adxl367_write_event_config(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ enum iio_event_type type,
+ enum iio_event_direction dir,
+ int state)
+{
+ struct adxl367_state *st = iio_priv(indio_dev);
+ enum adxl367_activity_type act;
+ int ret;
+
+ switch (dir) {
+ case IIO_EV_DIR_RISING:
+ act = ADXL367_ACTIVITY;
+ break;
+ case IIO_EV_DIR_FALLING:
+ act = ADXL367_INACTIVITY;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = iio_device_claim_direct_mode(indio_dev);
+ if (ret)
+ return ret;
+
+ mutex_lock(&st->lock);
+
+ ret = adxl367_set_measure_en(st, false);
+ if (ret)
+ goto out;
+
+ ret = adxl367_set_act_interrupt_en(st, act, state);
+ if (ret)
+ goto out;
+
+ ret = adxl367_set_act_en(st, act, state ? ADCL367_ACT_REF_ENABLED
+ : ADXL367_ACT_DISABLED);
+ if (ret)
+ goto out;
+
+ ret = adxl367_set_measure_en(st, true);
+
+out:
+ mutex_unlock(&st->lock);
+
+ iio_device_release_direct_mode(indio_dev);
+
+ return ret;
+}
+
+static ssize_t adxl367_get_fifo_enabled(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct adxl367_state *st = iio_priv(dev_to_iio_dev(dev));
+ enum adxl367_fifo_mode fifo_mode;
+ int ret;
+
+ ret = adxl367_get_fifo_mode(st, &fifo_mode);
+ if (ret)
+ return ret;
+
+ return sysfs_emit(buf, "%d\n", fifo_mode != ADXL367_FIFO_MODE_DISABLED);
+}
+
+static ssize_t adxl367_get_fifo_watermark(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct adxl367_state *st = iio_priv(dev_to_iio_dev(dev));
+ unsigned int fifo_watermark;
+
+ mutex_lock(&st->lock);
+ fifo_watermark = st->fifo_watermark;
+ mutex_unlock(&st->lock);
+
+ return sysfs_emit(buf, "%d\n", fifo_watermark);
+}
+
+static IIO_CONST_ATTR(hwfifo_watermark_min, "1");
+static IIO_CONST_ATTR(hwfifo_watermark_max,
+ __stringify(ADXL367_FIFO_MAX_WATERMARK));
+static IIO_DEVICE_ATTR(hwfifo_watermark, 0444,
+ adxl367_get_fifo_watermark, NULL, 0);
+static IIO_DEVICE_ATTR(hwfifo_enabled, 0444,
+ adxl367_get_fifo_enabled, NULL, 0);
+
+static const struct attribute *adxl367_fifo_attributes[] = {
+ &iio_const_attr_hwfifo_watermark_min.dev_attr.attr,
+ &iio_const_attr_hwfifo_watermark_max.dev_attr.attr,
+ &iio_dev_attr_hwfifo_watermark.dev_attr.attr,
+ &iio_dev_attr_hwfifo_enabled.dev_attr.attr,
+ NULL,
+};
+
+static int adxl367_set_watermark(struct iio_dev *indio_dev, unsigned int val)
+{
+ struct adxl367_state *st = iio_priv(indio_dev);
+ int ret;
+
+ if (val > ADXL367_FIFO_MAX_WATERMARK)
+ return -EINVAL;
+
+ mutex_lock(&st->lock);
+
+ ret = adxl367_set_measure_en(st, false);
+ if (ret)
+ goto out;
+
+ ret = adxl367_set_fifo_watermark(st, val);
+ if (ret)
+ goto out;
+
+ ret = adxl367_set_measure_en(st, true);
+
+out:
+ mutex_unlock(&st->lock);
+
+ return ret;
+}
+
+static bool adxl367_find_mask_fifo_format(const unsigned long *scan_mask,
+ enum adxl367_fifo_format *fifo_format)
+{
+ size_t size = ARRAY_SIZE(adxl367_fifo_formats);
+ int i;
+
+ for (i = 0; i < size; i++)
+ if (*scan_mask == adxl367_channel_masks[i])
+ break;
+
+ if (i == size)
+ return false;
+
+ *fifo_format = adxl367_fifo_formats[i];
+
+ return true;
+}
+
+static int adxl367_update_scan_mode(struct iio_dev *indio_dev,
+ const unsigned long *active_scan_mask)
+{
+ struct adxl367_state *st = iio_priv(indio_dev);
+ enum adxl367_fifo_format fifo_format;
+ unsigned int fifo_set_size;
+ int ret;
+
+ if (!adxl367_find_mask_fifo_format(active_scan_mask, &fifo_format))
+ return -EINVAL;
+
+ fifo_set_size = bitmap_weight(active_scan_mask, indio_dev->masklength);
+
+ mutex_lock(&st->lock);
+
+ ret = adxl367_set_measure_en(st, false);
+ if (ret)
+ goto out;
+
+ ret = adxl367_set_fifo_format(st, fifo_format);
+ if (ret)
+ goto out;
+
+ ret = adxl367_set_fifo_set_size(st, fifo_set_size);
+ if (ret)
+ goto out;
+
+ ret = adxl367_set_measure_en(st, true);
+
+out:
+ mutex_unlock(&st->lock);
+
+ return ret;
+}
+
+static int adxl367_buffer_postenable(struct iio_dev *indio_dev)
+{
+ struct adxl367_state *st = iio_priv(indio_dev);
+ int ret;
+
+ mutex_lock(&st->lock);
+
+ ret = adxl367_set_temp_adc_mask_en(st, indio_dev->active_scan_mask,
+ true);
+ if (ret)
+ goto out;
+
+ ret = adxl367_set_measure_en(st, false);
+ if (ret)
+ goto out;
+
+ ret = adxl367_set_fifo_watermark_interrupt_en(st, true);
+ if (ret)
+ goto out;
+
+ ret = adxl367_set_fifo_mode(st, ADXL367_FIFO_MODE_STREAM);
+ if (ret)
+ goto out;
+
+ ret = adxl367_set_measure_en(st, true);
+
+out:
+ mutex_unlock(&st->lock);
+
+ return ret;
+}
+
+static int adxl367_buffer_predisable(struct iio_dev *indio_dev)
+{
+ struct adxl367_state *st = iio_priv(indio_dev);
+ int ret;
+
+ mutex_lock(&st->lock);
+
+ ret = adxl367_set_measure_en(st, false);
+ if (ret)
+ goto out;
+
+ ret = adxl367_set_fifo_mode(st, ADXL367_FIFO_MODE_DISABLED);
+ if (ret)
+ goto out;
+
+ ret = adxl367_set_fifo_watermark_interrupt_en(st, false);
+ if (ret)
+ goto out;
+
+ ret = adxl367_set_measure_en(st, true);
+ if (ret)
+ goto out;
+
+ ret = adxl367_set_temp_adc_mask_en(st, indio_dev->active_scan_mask,
+ false);
+
+out:
+ mutex_unlock(&st->lock);
+
+ return ret;
+}
+
+static const struct iio_buffer_setup_ops adxl367_buffer_ops = {
+ .postenable = adxl367_buffer_postenable,
+ .predisable = adxl367_buffer_predisable,
+};
+
+static const struct iio_info adxl367_info = {
+ .read_raw = adxl367_read_raw,
+ .write_raw = adxl367_write_raw,
+ .write_raw_get_fmt = adxl367_write_raw_get_fmt,
+ .read_avail = adxl367_read_avail,
+ .read_event_config = adxl367_read_event_config,
+ .write_event_config = adxl367_write_event_config,
+ .read_event_value = adxl367_read_event_value,
+ .write_event_value = adxl367_write_event_value,
+ .debugfs_reg_access = adxl367_reg_access,
+ .hwfifo_set_watermark = adxl367_set_watermark,
+ .update_scan_mode = adxl367_update_scan_mode,
+};
+
+static const struct iio_event_spec adxl367_events[] = {
+ {
+ .type = IIO_EV_TYPE_MAG_REFERENCED,
+ .dir = IIO_EV_DIR_RISING,
+ .mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE) |
+ BIT(IIO_EV_INFO_PERIOD) |
+ BIT(IIO_EV_INFO_VALUE),
+ },
+ {
+ .type = IIO_EV_TYPE_MAG_REFERENCED,
+ .dir = IIO_EV_DIR_FALLING,
+ .mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE) |
+ BIT(IIO_EV_INFO_PERIOD) |
+ BIT(IIO_EV_INFO_VALUE),
+ },
+};
+
+#define ADXL367_ACCEL_CHANNEL(index, reg, axis) { \
+ .type = IIO_ACCEL, \
+ .address = (reg), \
+ .modified = 1, \
+ .channel2 = IIO_MOD_##axis, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+ .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SCALE), \
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+ .info_mask_shared_by_all_available = \
+ BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+ .event_spec = adxl367_events, \
+ .num_event_specs = ARRAY_SIZE(adxl367_events), \
+ .scan_index = (index), \
+ .scan_type = { \
+ .sign = 's', \
+ .realbits = 14, \
+ .storagebits = 16, \
+ .endianness = IIO_BE, \
+ }, \
+}
+
+#define ADXL367_CHANNEL(index, reg, _type) { \
+ .type = (_type), \
+ .address = (reg), \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_OFFSET) | \
+ BIT(IIO_CHAN_INFO_SCALE), \
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+ .scan_index = (index), \
+ .scan_type = { \
+ .sign = 's', \
+ .realbits = 14, \
+ .storagebits = 16, \
+ .endianness = IIO_BE, \
+ }, \
+}
+
+static const struct iio_chan_spec adxl367_channels[] = {
+ ADXL367_ACCEL_CHANNEL(ADXL367_X_CHANNEL_INDEX, ADXL367_REG_X_DATA_H, X),
+ ADXL367_ACCEL_CHANNEL(ADXL367_Y_CHANNEL_INDEX, ADXL367_REG_Y_DATA_H, Y),
+ ADXL367_ACCEL_CHANNEL(ADXL367_Z_CHANNEL_INDEX, ADXL367_REG_Z_DATA_H, Z),
+ ADXL367_CHANNEL(ADXL367_TEMP_CHANNEL_INDEX, ADXL367_REG_TEMP_DATA_H,
+ IIO_TEMP),
+ ADXL367_CHANNEL(ADXL367_EX_ADC_CHANNEL_INDEX, ADXL367_REG_EX_ADC_DATA_H,
+ IIO_VOLTAGE),
+};
+
+static int adxl367_verify_devid(struct adxl367_state *st)
+{
+ unsigned int val;
+ int ret;
+
+ ret = regmap_read_poll_timeout(st->regmap, ADXL367_REG_DEVID, val,
+ val == ADXL367_DEVID_AD, 1000, 10000);
+ if (ret)
+ return dev_err_probe(st->dev, -ENODEV,
+ "Invalid dev id 0x%02X, expected 0x%02X\n",
+ val, ADXL367_DEVID_AD);
+
+ return 0;
+}
+
+static int adxl367_setup(struct adxl367_state *st)
+{
+ int ret;
+
+ ret = _adxl367_set_act_threshold(st, ADXL367_ACTIVITY,
+ ADXL367_2G_RANGE_1G);
+ if (ret)
+ return ret;
+
+ ret = _adxl367_set_act_threshold(st, ADXL367_INACTIVITY,
+ ADXL367_2G_RANGE_100MG);
+ if (ret)
+ return ret;
+
+ ret = adxl367_set_act_proc_mode(st, ADXL367_LOOPED);
+ if (ret)
+ return ret;
+
+ ret = _adxl367_set_odr(st, ADXL367_ODR_400HZ);
+ if (ret)
+ return ret;
+
+ ret = _adxl367_set_act_time_ms(st, 10);
+ if (ret)
+ return ret;
+
+ ret = _adxl367_set_inact_time_ms(st, 10000);
+ if (ret)
+ return ret;
+
+ return adxl367_set_measure_en(st, true);
+}
+
+static void adxl367_disable_regulators(void *data)
+{
+ struct adxl367_state *st = data;
+
+ regulator_bulk_disable(ARRAY_SIZE(st->regulators), st->regulators);
+}
+
+int adxl367_probe(struct device *dev, const struct adxl367_ops *ops,
+ void *context, struct regmap *regmap, int irq)
+{
+ struct iio_dev *indio_dev;
+ struct adxl367_state *st;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ st = iio_priv(indio_dev);
+ st->dev = dev;
+ st->regmap = regmap;
+ st->context = context;
+ st->ops = ops;
+
+ mutex_init(&st->lock);
+
+ indio_dev->channels = adxl367_channels;
+ indio_dev->num_channels = ARRAY_SIZE(adxl367_channels);
+ indio_dev->available_scan_masks = adxl367_channel_masks;
+ indio_dev->name = "adxl367";
+ indio_dev->info = &adxl367_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+
+ st->regulators[0].supply = "vdd";
+ st->regulators[1].supply = "vddio";
+
+ ret = devm_regulator_bulk_get(st->dev, ARRAY_SIZE(st->regulators),
+ st->regulators);
+ if (ret)
+ return dev_err_probe(st->dev, ret,
+ "Failed to get regulators\n");
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(st->regulators), st->regulators);
+ if (ret)
+ return dev_err_probe(st->dev, ret,
+ "Failed to enable regulators\n");
+
+ ret = devm_add_action_or_reset(st->dev, adxl367_disable_regulators, st);
+ if (ret)
+ return dev_err_probe(st->dev, ret,
+ "Failed to add regulators disable action\n");
+
+ ret = regmap_write(st->regmap, ADXL367_REG_RESET, ADXL367_RESET_CODE);
+ if (ret)
+ return ret;
+
+ ret = adxl367_verify_devid(st);
+ if (ret)
+ return ret;
+
+ ret = adxl367_setup(st);
+ if (ret)
+ return ret;
+
+ ret = devm_iio_kfifo_buffer_setup_ext(st->dev, indio_dev,
+ INDIO_BUFFER_SOFTWARE,
+ &adxl367_buffer_ops,
+ adxl367_fifo_attributes);
+ if (ret)
+ return ret;
+
+ ret = devm_request_threaded_irq(st->dev, irq, NULL,
+ adxl367_irq_handler, IRQF_ONESHOT,
+ indio_dev->name, indio_dev);
+ if (ret)
+ return dev_err_probe(st->dev, ret, "Failed to request irq\n");
+
+ return devm_iio_device_register(dev, indio_dev);
+}
+EXPORT_SYMBOL_NS_GPL(adxl367_probe, IIO_ADXL367);
+
+MODULE_AUTHOR("Cosmin Tanislav <cosmin.tanislav@analog.com>");
+MODULE_DESCRIPTION("Analog Devices ADXL367 3-axis accelerometer driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/accel/adxl367.h b/drivers/iio/accel/adxl367.h
new file mode 100644
index 000000000000..4a42622149b1
--- /dev/null
+++ b/drivers/iio/accel/adxl367.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2021 Analog Devices, Inc.
+ * Author: Cosmin Tanislav <cosmin.tanislav@analog.com>
+ */
+
+#ifndef _ADXL367_H_
+#define _ADXL367_H_
+
+#include <linux/types.h>
+
+struct device;
+struct regmap;
+
+struct adxl367_ops {
+ int (*read_fifo)(void *context, __be16 *fifo_buf,
+ unsigned int fifo_entries);
+};
+
+int adxl367_probe(struct device *dev, const struct adxl367_ops *ops,
+ void *context, struct regmap *regmap, int irq);
+
+#endif /* _ADXL367_H_ */
diff --git a/drivers/iio/accel/adxl367_i2c.c b/drivers/iio/accel/adxl367_i2c.c
new file mode 100644
index 000000000000..3606efa25835
--- /dev/null
+++ b/drivers/iio/accel/adxl367_i2c.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021 Analog Devices, Inc.
+ * Author: Cosmin Tanislav <cosmin.tanislav@analog.com>
+ */
+
+#include <linux/i2c.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+
+#include "adxl367.h"
+
+#define ADXL367_I2C_FIFO_DATA 0x42
+
+struct adxl367_i2c_state {
+ struct regmap *regmap;
+};
+
+static bool adxl367_readable_noinc_reg(struct device *dev, unsigned int reg)
+{
+ return reg == ADXL367_I2C_FIFO_DATA;
+}
+
+static int adxl367_i2c_read_fifo(void *context, __be16 *fifo_buf,
+ unsigned int fifo_entries)
+{
+ struct adxl367_i2c_state *st = context;
+
+ return regmap_noinc_read(st->regmap, ADXL367_I2C_FIFO_DATA, fifo_buf,
+ fifo_entries * sizeof(*fifo_buf));
+}
+
+static const struct regmap_config adxl367_i2c_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .readable_noinc_reg = adxl367_readable_noinc_reg,
+};
+
+static const struct adxl367_ops adxl367_i2c_ops = {
+ .read_fifo = adxl367_i2c_read_fifo,
+};
+
+static int adxl367_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct adxl367_i2c_state *st;
+ struct regmap *regmap;
+
+ st = devm_kzalloc(&client->dev, sizeof(*st), GFP_KERNEL);
+ if (!st)
+ return -ENOMEM;
+
+ regmap = devm_regmap_init_i2c(client, &adxl367_i2c_regmap_config);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ st->regmap = regmap;
+
+ return adxl367_probe(&client->dev, &adxl367_i2c_ops, st, regmap,
+ client->irq);
+}
+
+static const struct i2c_device_id adxl367_i2c_id[] = {
+ { "adxl367", 0 },
+ { },
+};
+MODULE_DEVICE_TABLE(i2c, adxl367_i2c_id);
+
+static const struct of_device_id adxl367_of_match[] = {
+ { .compatible = "adi,adxl367" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, adxl367_of_match);
+
+static struct i2c_driver adxl367_i2c_driver = {
+ .driver = {
+ .name = "adxl367_i2c",
+ .of_match_table = adxl367_of_match,
+ },
+ .probe = adxl367_i2c_probe,
+ .id_table = adxl367_i2c_id,
+};
+
+module_i2c_driver(adxl367_i2c_driver);
+
+MODULE_IMPORT_NS(IIO_ADXL367);
+MODULE_AUTHOR("Cosmin Tanislav <cosmin.tanislav@analog.com>");
+MODULE_DESCRIPTION("Analog Devices ADXL367 3-axis accelerometer I2C driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/accel/adxl367_spi.c b/drivers/iio/accel/adxl367_spi.c
new file mode 100644
index 000000000000..26dfc821ebbe
--- /dev/null
+++ b/drivers/iio/accel/adxl367_spi.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021 Analog Devices, Inc.
+ * Author: Cosmin Tanislav <cosmin.tanislav@analog.com>
+ */
+
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/spi/spi.h>
+
+#include "adxl367.h"
+
+#define ADXL367_SPI_WRITE_COMMAND 0x0A
+#define ADXL367_SPI_READ_COMMAND 0x0B
+#define ADXL367_SPI_FIFO_COMMAND 0x0D
+
+struct adxl367_spi_state {
+ struct spi_device *spi;
+
+ struct spi_message reg_write_msg;
+ struct spi_transfer reg_write_xfer[2];
+
+ struct spi_message reg_read_msg;
+ struct spi_transfer reg_read_xfer[2];
+
+ struct spi_message fifo_msg;
+ struct spi_transfer fifo_xfer[2];
+
+ /*
+ * DMA (thus cache coherency maintenance) requires the
+ * transfer buffers to live in their own cache lines.
+ */
+ u8 reg_write_tx_buf[1] ____cacheline_aligned;
+ u8 reg_read_tx_buf[2];
+ u8 fifo_tx_buf[1];
+};
+
+static int adxl367_read_fifo(void *context, __be16 *fifo_buf,
+ unsigned int fifo_entries)
+{
+ struct adxl367_spi_state *st = context;
+
+ st->fifo_xfer[1].rx_buf = fifo_buf;
+ st->fifo_xfer[1].len = fifo_entries * sizeof(*fifo_buf);
+
+ return spi_sync(st->spi, &st->fifo_msg);
+}
+
+static int adxl367_read(void *context, const void *reg_buf, size_t reg_size,
+ void *val_buf, size_t val_size)
+{
+ struct adxl367_spi_state *st = context;
+ u8 reg = ((const u8 *)reg_buf)[0];
+
+ st->reg_read_tx_buf[1] = reg;
+ st->reg_read_xfer[1].rx_buf = val_buf;
+ st->reg_read_xfer[1].len = val_size;
+
+ return spi_sync(st->spi, &st->reg_read_msg);
+}
+
+static int adxl367_write(void *context, const void *val_buf, size_t val_size)
+{
+ struct adxl367_spi_state *st = context;
+
+ st->reg_write_xfer[1].tx_buf = val_buf;
+ st->reg_write_xfer[1].len = val_size;
+
+ return spi_sync(st->spi, &st->reg_write_msg);
+}
+
+static struct regmap_bus adxl367_spi_regmap_bus = {
+ .read = adxl367_read,
+ .write = adxl367_write,
+};
+
+static const struct regmap_config adxl367_spi_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+};
+
+static const struct adxl367_ops adxl367_spi_ops = {
+ .read_fifo = adxl367_read_fifo,
+};
+
+static int adxl367_spi_probe(struct spi_device *spi)
+{
+ struct adxl367_spi_state *st;
+ struct regmap *regmap;
+
+ st = devm_kzalloc(&spi->dev, sizeof(*st), GFP_KERNEL);
+ if (!st)
+ return -ENOMEM;
+
+ st->spi = spi;
+
+ /*
+ * Xfer: [XFR1] [ XFR2 ]
+ * Master: 0x0A ADDR DATA0 DATA1 ... DATAN
+ * Slave: .... ..........................
+ */
+ st->reg_write_tx_buf[0] = ADXL367_SPI_WRITE_COMMAND;
+ st->reg_write_xfer[0].tx_buf = st->reg_write_tx_buf;
+ st->reg_write_xfer[0].len = sizeof(st->reg_write_tx_buf);
+ spi_message_init_with_transfers(&st->reg_write_msg,
+ st->reg_write_xfer, 2);
+
+ /*
+ * Xfer: [ XFR1 ] [ XFR2 ]
+ * Master: 0x0B ADDR .....................
+ * Slave: ......... DATA0 DATA1 ... DATAN
+ */
+ st->reg_read_tx_buf[0] = ADXL367_SPI_READ_COMMAND;
+ st->reg_read_xfer[0].tx_buf = st->reg_read_tx_buf;
+ st->reg_read_xfer[0].len = sizeof(st->reg_read_tx_buf);
+ spi_message_init_with_transfers(&st->reg_read_msg,
+ st->reg_read_xfer, 2);
+
+ /*
+ * Xfer: [XFR1] [ XFR2 ]
+ * Master: 0x0D .....................
+ * Slave: .... DATA0 DATA1 ... DATAN
+ */
+ st->fifo_tx_buf[0] = ADXL367_SPI_FIFO_COMMAND;
+ st->fifo_xfer[0].tx_buf = st->fifo_tx_buf;
+ st->fifo_xfer[0].len = sizeof(st->fifo_tx_buf);
+ spi_message_init_with_transfers(&st->fifo_msg, st->fifo_xfer, 2);
+
+ regmap = devm_regmap_init(&spi->dev, &adxl367_spi_regmap_bus, st,
+ &adxl367_spi_regmap_config);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ return adxl367_probe(&spi->dev, &adxl367_spi_ops, st, regmap, spi->irq);
+}
+
+static const struct spi_device_id adxl367_spi_id[] = {
+ { "adxl367", 0 },
+ { },
+};
+MODULE_DEVICE_TABLE(spi, adxl367_spi_id);
+
+static const struct of_device_id adxl367_of_match[] = {
+ { .compatible = "adi,adxl367" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, adxl367_of_match);
+
+static struct spi_driver adxl367_spi_driver = {
+ .driver = {
+ .name = "adxl367_spi",
+ .of_match_table = adxl367_of_match,
+ },
+ .probe = adxl367_spi_probe,
+ .id_table = adxl367_spi_id,
+};
+
+module_spi_driver(adxl367_spi_driver);
+
+MODULE_IMPORT_NS(IIO_ADXL367);
+MODULE_AUTHOR("Cosmin Tanislav <cosmin.tanislav@analog.com>");
+MODULE_DESCRIPTION("Analog Devices ADXL367 3-axis accelerometer SPI driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/accel/adxl372.c b/drivers/iio/accel/adxl372.c
index 758952584f8c..e3ecbaee61f7 100644
--- a/drivers/iio/accel/adxl372.c
+++ b/drivers/iio/accel/adxl372.c
@@ -1176,7 +1176,7 @@ bool adxl372_readable_noinc_reg(struct device *dev, unsigned int reg)
{
return (reg == ADXL372_FIFO_DATA);
}
-EXPORT_SYMBOL_GPL(adxl372_readable_noinc_reg);
+EXPORT_SYMBOL_NS_GPL(adxl372_readable_noinc_reg, IIO_ADXL372);
int adxl372_probe(struct device *dev, struct regmap *regmap,
int irq, const char *name)
@@ -1260,7 +1260,7 @@ int adxl372_probe(struct device *dev, struct regmap *regmap,
return devm_iio_device_register(dev, indio_dev);
}
-EXPORT_SYMBOL_GPL(adxl372_probe);
+EXPORT_SYMBOL_NS_GPL(adxl372_probe, IIO_ADXL372);
MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>");
MODULE_DESCRIPTION("Analog Devices ADXL372 3-axis accelerometer driver");
diff --git a/drivers/iio/accel/adxl372_i2c.c b/drivers/iio/accel/adxl372_i2c.c
index 9a07ab3d151a..4efb70a5fe40 100644
--- a/drivers/iio/accel/adxl372_i2c.c
+++ b/drivers/iio/accel/adxl372_i2c.c
@@ -67,3 +67,4 @@ module_i2c_driver(adxl372_i2c_driver);
MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>");
MODULE_DESCRIPTION("Analog Devices ADXL372 3-axis accelerometer I2C driver");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(IIO_ADXL372);
diff --git a/drivers/iio/accel/adxl372_spi.c b/drivers/iio/accel/adxl372_spi.c
index 1f1352fee99a..2bd267a22f29 100644
--- a/drivers/iio/accel/adxl372_spi.c
+++ b/drivers/iio/accel/adxl372_spi.c
@@ -59,3 +59,4 @@ module_spi_driver(adxl372_spi_driver);
MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>");
MODULE_DESCRIPTION("Analog Devices ADXL372 3-axis accelerometer SPI driver");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(IIO_ADXL372);
diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c
index d8a454c266d5..4f73bc827eec 100644
--- a/drivers/iio/accel/bma180.c
+++ b/drivers/iio/accel/bma180.c
@@ -1065,7 +1065,6 @@ static int bma180_remove(struct i2c_client *client)
return 0;
}
-#ifdef CONFIG_PM_SLEEP
static int bma180_suspend(struct device *dev)
{
struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
@@ -1092,11 +1091,7 @@ static int bma180_resume(struct device *dev)
return ret;
}
-static SIMPLE_DEV_PM_OPS(bma180_pm_ops, bma180_suspend, bma180_resume);
-#define BMA180_PM_OPS (&bma180_pm_ops)
-#else
-#define BMA180_PM_OPS NULL
-#endif
+static DEFINE_SIMPLE_DEV_PM_OPS(bma180_pm_ops, bma180_suspend, bma180_resume);
static const struct i2c_device_id bma180_ids[] = {
{ "bma023", BMA023 },
@@ -1137,7 +1132,7 @@ MODULE_DEVICE_TABLE(of, bma180_of_match);
static struct i2c_driver bma180_driver = {
.driver = {
.name = "bma180",
- .pm = BMA180_PM_OPS,
+ .pm = pm_sleep_ptr(&bma180_pm_ops),
.of_match_table = bma180_of_match,
},
.probe = bma180_probe,
diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c
index fd2647b728d3..043002fe6f63 100644
--- a/drivers/iio/accel/bma400_core.c
+++ b/drivers/iio/accel/bma400_core.c
@@ -136,7 +136,7 @@ const struct regmap_config bma400_regmap_config = {
.writeable_reg = bma400_is_writable_reg,
.volatile_reg = bma400_is_volatile_reg,
};
-EXPORT_SYMBOL(bma400_regmap_config);
+EXPORT_SYMBOL_NS(bma400_regmap_config, IIO_BMA400);
static const struct iio_mount_matrix *
bma400_accel_get_mount_matrix(const struct iio_dev *indio_dev,
@@ -826,7 +826,7 @@ int bma400_probe(struct device *dev, struct regmap *regmap, const char *name)
return iio_device_register(indio_dev);
}
-EXPORT_SYMBOL(bma400_probe);
+EXPORT_SYMBOL_NS(bma400_probe, IIO_BMA400);
void bma400_remove(struct device *dev)
{
@@ -846,7 +846,7 @@ void bma400_remove(struct device *dev)
iio_device_unregister(indio_dev);
}
-EXPORT_SYMBOL(bma400_remove);
+EXPORT_SYMBOL_NS(bma400_remove, IIO_BMA400);
MODULE_AUTHOR("Dan Robertson <dan@dlrobertson.com>");
MODULE_DESCRIPTION("Bosch BMA400 triaxial acceleration sensor core");
diff --git a/drivers/iio/accel/bma400_i2c.c b/drivers/iio/accel/bma400_i2c.c
index f50df5310beb..da104ffd3fe0 100644
--- a/drivers/iio/accel/bma400_i2c.c
+++ b/drivers/iio/accel/bma400_i2c.c
@@ -61,3 +61,4 @@ module_i2c_driver(bma400_i2c_driver);
MODULE_AUTHOR("Dan Robertson <dan@dlrobertson.com>");
MODULE_DESCRIPTION("Bosch BMA400 triaxial acceleration sensor (I2C)");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(IIO_BMA400);
diff --git a/drivers/iio/accel/bma400_spi.c b/drivers/iio/accel/bma400_spi.c
index 9040a717b247..51f23bdc0ea5 100644
--- a/drivers/iio/accel/bma400_spi.c
+++ b/drivers/iio/accel/bma400_spi.c
@@ -118,3 +118,4 @@ module_spi_driver(bma400_spi_driver);
MODULE_AUTHOR("Dan Robertson <dan@dlrobertson.com>");
MODULE_DESCRIPTION("Bosch BMA400 triaxial acceleration sensor (SPI)");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(IIO_BMA400);
diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c
index d11f668016a6..7516d7dde1af 100644
--- a/drivers/iio/accel/bmc150-accel-core.c
+++ b/drivers/iio/accel/bmc150-accel-core.c
@@ -203,7 +203,7 @@ const struct regmap_config bmc150_regmap_conf = {
.val_bits = 8,
.max_register = 0x3f,
};
-EXPORT_SYMBOL_GPL(bmc150_regmap_conf);
+EXPORT_SYMBOL_NS_GPL(bmc150_regmap_conf, IIO_BMC150);
static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
enum bmc150_power_modes mode,
@@ -1801,7 +1801,7 @@ err_disable_regulators:
return ret;
}
-EXPORT_SYMBOL_GPL(bmc150_accel_core_probe);
+EXPORT_SYMBOL_NS_GPL(bmc150_accel_core_probe, IIO_BMC150);
void bmc150_accel_core_remove(struct device *dev)
{
@@ -1824,7 +1824,7 @@ void bmc150_accel_core_remove(struct device *dev)
regulator_bulk_disable(ARRAY_SIZE(data->regulators),
data->regulators);
}
-EXPORT_SYMBOL_GPL(bmc150_accel_core_remove);
+EXPORT_SYMBOL_NS_GPL(bmc150_accel_core_remove, IIO_BMC150);
#ifdef CONFIG_PM_SLEEP
static int bmc150_accel_suspend(struct device *dev)
@@ -1899,7 +1899,7 @@ const struct dev_pm_ops bmc150_accel_pm_ops = {
SET_RUNTIME_PM_OPS(bmc150_accel_runtime_suspend,
bmc150_accel_runtime_resume, NULL)
};
-EXPORT_SYMBOL_GPL(bmc150_accel_pm_ops);
+EXPORT_SYMBOL_NS_GPL(bmc150_accel_pm_ops, IIO_BMC150);
MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/accel/bmc150-accel-i2c.c b/drivers/iio/accel/bmc150-accel-i2c.c
index 9e52df9a8f07..dff4d7dd101c 100644
--- a/drivers/iio/accel/bmc150-accel-i2c.c
+++ b/drivers/iio/accel/bmc150-accel-i2c.c
@@ -280,3 +280,4 @@ module_i2c_driver(bmc150_accel_driver);
MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("BMC150 I2C accelerometer driver");
+MODULE_IMPORT_NS(IIO_BMC150);
diff --git a/drivers/iio/accel/bmc150-accel-spi.c b/drivers/iio/accel/bmc150-accel-spi.c
index 80007cc2d044..921fb46be0b8 100644
--- a/drivers/iio/accel/bmc150-accel-spi.c
+++ b/drivers/iio/accel/bmc150-accel-spi.c
@@ -82,3 +82,4 @@ module_spi_driver(bmc150_accel_driver);
MODULE_AUTHOR("Markus Pargmann <mpa@pengutronix.de>");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("BMC150 SPI accelerometer driver");
+MODULE_IMPORT_NS(IIO_BMC150);
diff --git a/drivers/iio/accel/bmi088-accel-core.c b/drivers/iio/accel/bmi088-accel-core.c
index d74465214feb..8b2728bbcade 100644
--- a/drivers/iio/accel/bmi088-accel-core.c
+++ b/drivers/iio/accel/bmi088-accel-core.c
@@ -146,7 +146,7 @@ const struct regmap_config bmi088_regmap_conf = {
.volatile_table = &bmi088_volatile_table,
.cache_type = REGCACHE_RBTREE,
};
-EXPORT_SYMBOL_GPL(bmi088_regmap_conf);
+EXPORT_SYMBOL_NS_GPL(bmi088_regmap_conf, IIO_BMI088);
static int bmi088_accel_power_up(struct bmi088_accel_data *data)
{
@@ -533,7 +533,7 @@ int bmi088_accel_core_probe(struct device *dev, struct regmap *regmap,
return ret;
}
-EXPORT_SYMBOL_GPL(bmi088_accel_core_probe);
+EXPORT_SYMBOL_NS_GPL(bmi088_accel_core_probe, IIO_BMI088);
void bmi088_accel_core_remove(struct device *dev)
@@ -547,7 +547,7 @@ void bmi088_accel_core_remove(struct device *dev)
pm_runtime_set_suspended(dev);
bmi088_accel_power_down(data);
}
-EXPORT_SYMBOL_GPL(bmi088_accel_core_remove);
+EXPORT_SYMBOL_NS_GPL(bmi088_accel_core_remove, IIO_BMI088);
static int __maybe_unused bmi088_accel_runtime_suspend(struct device *dev)
{
@@ -571,7 +571,7 @@ const struct dev_pm_ops bmi088_accel_pm_ops = {
SET_RUNTIME_PM_OPS(bmi088_accel_runtime_suspend,
bmi088_accel_runtime_resume, NULL)
};
-EXPORT_SYMBOL_GPL(bmi088_accel_pm_ops);
+EXPORT_SYMBOL_NS_GPL(bmi088_accel_pm_ops, IIO_BMI088);
MODULE_AUTHOR("Niek van Agt <niek.van.agt@topicproducts.com>");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/accel/bmi088-accel-spi.c b/drivers/iio/accel/bmi088-accel-spi.c
index 06d99d9949f3..167c36cf1eb8 100644
--- a/drivers/iio/accel/bmi088-accel-spi.c
+++ b/drivers/iio/accel/bmi088-accel-spi.c
@@ -81,3 +81,4 @@ module_spi_driver(bmi088_accel_driver);
MODULE_AUTHOR("Niek van Agt <niek.van.agt@topicproducts.com>");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("BMI088 accelerometer driver (SPI)");
+MODULE_IMPORT_NS(IIO_BMI088);
diff --git a/drivers/iio/accel/da280.c b/drivers/iio/accel/da280.c
index 9633bdae5fd4..04e9c5678964 100644
--- a/drivers/iio/accel/da280.c
+++ b/drivers/iio/accel/da280.c
@@ -153,7 +153,6 @@ static int da280_probe(struct i2c_client *client,
return devm_iio_device_register(&client->dev, indio_dev);
}
-#ifdef CONFIG_PM_SLEEP
static int da280_suspend(struct device *dev)
{
return da280_enable(to_i2c_client(dev), false);
@@ -163,9 +162,8 @@ static int da280_resume(struct device *dev)
{
return da280_enable(to_i2c_client(dev), true);
}
-#endif
-static SIMPLE_DEV_PM_OPS(da280_pm_ops, da280_suspend, da280_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(da280_pm_ops, da280_suspend, da280_resume);
static const struct acpi_device_id da280_acpi_match[] = {
{"MIRAACC", da280},
@@ -184,7 +182,7 @@ static struct i2c_driver da280_driver = {
.driver = {
.name = "da280",
.acpi_match_table = ACPI_PTR(da280_acpi_match),
- .pm = &da280_pm_ops,
+ .pm = pm_sleep_ptr(&da280_pm_ops),
},
.probe = da280_probe,
.id_table = da280_i2c_id,
diff --git a/drivers/iio/accel/da311.c b/drivers/iio/accel/da311.c
index 04e13487e706..ec4e29d260f7 100644
--- a/drivers/iio/accel/da311.c
+++ b/drivers/iio/accel/da311.c
@@ -256,7 +256,6 @@ static int da311_probe(struct i2c_client *client,
return devm_iio_device_register(&client->dev, indio_dev);
}
-#ifdef CONFIG_PM_SLEEP
static int da311_suspend(struct device *dev)
{
return da311_enable(to_i2c_client(dev), false);
@@ -266,9 +265,8 @@ static int da311_resume(struct device *dev)
{
return da311_enable(to_i2c_client(dev), true);
}
-#endif
-static SIMPLE_DEV_PM_OPS(da311_pm_ops, da311_suspend, da311_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(da311_pm_ops, da311_suspend, da311_resume);
static const struct i2c_device_id da311_i2c_id[] = {
{"da311", 0},
@@ -279,7 +277,7 @@ MODULE_DEVICE_TABLE(i2c, da311_i2c_id);
static struct i2c_driver da311_driver = {
.driver = {
.name = "da311",
- .pm = &da311_pm_ops,
+ .pm = pm_sleep_ptr(&da311_pm_ops),
},
.probe = da311_probe,
.id_table = da311_i2c_id,
diff --git a/drivers/iio/accel/dmard06.c b/drivers/iio/accel/dmard06.c
index de2868c28d95..4b69c8530f5e 100644
--- a/drivers/iio/accel/dmard06.c
+++ b/drivers/iio/accel/dmard06.c
@@ -170,7 +170,6 @@ static int dmard06_probe(struct i2c_client *client,
return devm_iio_device_register(&client->dev, indio_dev);
}
-#ifdef CONFIG_PM_SLEEP
static int dmard06_suspend(struct device *dev)
{
struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
@@ -199,11 +198,8 @@ static int dmard06_resume(struct device *dev)
return 0;
}
-static SIMPLE_DEV_PM_OPS(dmard06_pm_ops, dmard06_suspend, dmard06_resume);
-#define DMARD06_PM_OPS (&dmard06_pm_ops)
-#else
-#define DMARD06_PM_OPS NULL
-#endif
+static DEFINE_SIMPLE_DEV_PM_OPS(dmard06_pm_ops, dmard06_suspend,
+ dmard06_resume);
static const struct i2c_device_id dmard06_id[] = {
{ "dmard05", 0 },
@@ -227,7 +223,7 @@ static struct i2c_driver dmard06_driver = {
.driver = {
.name = DMARD06_DRV_NAME,
.of_match_table = dmard06_of_match,
- .pm = DMARD06_PM_OPS,
+ .pm = pm_sleep_ptr(&dmard06_pm_ops),
},
};
module_i2c_driver(dmard06_driver);
diff --git a/drivers/iio/accel/dmard09.c b/drivers/iio/accel/dmard09.c
index e6e28c964777..53ab6078cb7f 100644
--- a/drivers/iio/accel/dmard09.c
+++ b/drivers/iio/accel/dmard09.c
@@ -126,7 +126,7 @@ static int dmard09_probe(struct i2c_client *client,
}
static const struct i2c_device_id dmard09_id[] = {
- { "dmard09", 0},
+ { "dmard09", 0 },
{ },
};
diff --git a/drivers/iio/accel/dmard10.c b/drivers/iio/accel/dmard10.c
index f9f173eec202..8ac62ec0a04a 100644
--- a/drivers/iio/accel/dmard10.c
+++ b/drivers/iio/accel/dmard10.c
@@ -218,7 +218,6 @@ static int dmard10_probe(struct i2c_client *client,
return devm_iio_device_register(&client->dev, indio_dev);
}
-#ifdef CONFIG_PM_SLEEP
static int dmard10_suspend(struct device *dev)
{
return dmard10_shutdown(to_i2c_client(dev));
@@ -228,9 +227,9 @@ static int dmard10_resume(struct device *dev)
{
return dmard10_reset(to_i2c_client(dev));
}
-#endif
-static SIMPLE_DEV_PM_OPS(dmard10_pm_ops, dmard10_suspend, dmard10_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(dmard10_pm_ops, dmard10_suspend,
+ dmard10_resume);
static const struct i2c_device_id dmard10_i2c_id[] = {
{"dmard10", 0},
@@ -241,7 +240,7 @@ MODULE_DEVICE_TABLE(i2c, dmard10_i2c_id);
static struct i2c_driver dmard10_driver = {
.driver = {
.name = "dmard10",
- .pm = &dmard10_pm_ops,
+ .pm = pm_sleep_ptr(&dmard10_pm_ops),
},
.probe = dmard10_probe,
.id_table = dmard10_i2c_id,
diff --git a/drivers/iio/accel/fxls8962af-core.c b/drivers/iio/accel/fxls8962af-core.c
index f7fd9e046588..a9d2f10d5d45 100644
--- a/drivers/iio/accel/fxls8962af-core.c
+++ b/drivers/iio/accel/fxls8962af-core.c
@@ -178,7 +178,7 @@ const struct regmap_config fxls8962af_i2c_regmap_conf = {
.val_bits = 8,
.max_register = FXLS8962AF_MAX_REG,
};
-EXPORT_SYMBOL_GPL(fxls8962af_i2c_regmap_conf);
+EXPORT_SYMBOL_NS_GPL(fxls8962af_i2c_regmap_conf, IIO_FXLS8962AF);
const struct regmap_config fxls8962af_spi_regmap_conf = {
.reg_bits = 8,
@@ -186,7 +186,7 @@ const struct regmap_config fxls8962af_spi_regmap_conf = {
.val_bits = 8,
.max_register = FXLS8962AF_MAX_REG,
};
-EXPORT_SYMBOL_GPL(fxls8962af_spi_regmap_conf);
+EXPORT_SYMBOL_NS_GPL(fxls8962af_spi_regmap_conf, IIO_FXLS8962AF);
enum {
fxls8962af_idx_x,
@@ -1240,7 +1240,7 @@ int fxls8962af_core_probe(struct device *dev, struct regmap *regmap, int irq)
return devm_iio_device_register(dev, indio_dev);
}
-EXPORT_SYMBOL_GPL(fxls8962af_core_probe);
+EXPORT_SYMBOL_NS_GPL(fxls8962af_core_probe, IIO_FXLS8962AF);
static int __maybe_unused fxls8962af_runtime_suspend(struct device *dev)
{
@@ -1306,7 +1306,7 @@ const struct dev_pm_ops fxls8962af_pm_ops = {
SET_RUNTIME_PM_OPS(fxls8962af_runtime_suspend,
fxls8962af_runtime_resume, NULL)
};
-EXPORT_SYMBOL_GPL(fxls8962af_pm_ops);
+EXPORT_SYMBOL_NS_GPL(fxls8962af_pm_ops, IIO_FXLS8962AF);
MODULE_AUTHOR("Sean Nyekjaer <sean@geanix.com>");
MODULE_DESCRIPTION("NXP FXLS8962AF/FXLS8964AF accelerometer driver");
diff --git a/drivers/iio/accel/fxls8962af-i2c.c b/drivers/iio/accel/fxls8962af-i2c.c
index 6bde9891effb..8fbadfea1620 100644
--- a/drivers/iio/accel/fxls8962af-i2c.c
+++ b/drivers/iio/accel/fxls8962af-i2c.c
@@ -55,3 +55,4 @@ module_i2c_driver(fxls8962af_driver);
MODULE_AUTHOR("Sean Nyekjaer <sean@geanix.com>");
MODULE_DESCRIPTION("NXP FXLS8962AF/FXLS8964AF accelerometer i2c driver");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS(IIO_FXLS8962AF);
diff --git a/drivers/iio/accel/fxls8962af-spi.c b/drivers/iio/accel/fxls8962af-spi.c
index 6f4dff3238d3..885b3ab7fcb5 100644
--- a/drivers/iio/accel/fxls8962af-spi.c
+++ b/drivers/iio/accel/fxls8962af-spi.c
@@ -55,3 +55,4 @@ module_spi_driver(fxls8962af_driver);
MODULE_AUTHOR("Sean Nyekjaer <sean@geanix.com>");
MODULE_DESCRIPTION("NXP FXLS8962AF/FXLS8964AF accelerometer spi driver");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS(IIO_FXLS8962AF);
diff --git a/drivers/iio/accel/kxsd9-i2c.c b/drivers/iio/accel/kxsd9-i2c.c
index 274b41a6e603..c8dc52f11037 100644
--- a/drivers/iio/accel/kxsd9-i2c.c
+++ b/drivers/iio/accel/kxsd9-i2c.c
@@ -65,3 +65,4 @@ module_i2c_driver(kxsd9_i2c_driver);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("KXSD9 accelerometer I2C interface");
+MODULE_IMPORT_NS(IIO_KXSD9);
diff --git a/drivers/iio/accel/kxsd9-spi.c b/drivers/iio/accel/kxsd9-spi.c
index 57c451cfb9e5..ec17e35e573e 100644
--- a/drivers/iio/accel/kxsd9-spi.c
+++ b/drivers/iio/accel/kxsd9-spi.c
@@ -64,3 +64,4 @@ module_spi_driver(kxsd9_spi_driver);
MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
MODULE_DESCRIPTION("Kionix KXSD9 SPI driver");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS(IIO_KXSD9);
diff --git a/drivers/iio/accel/kxsd9.c b/drivers/iio/accel/kxsd9.c
index 552eba5e8b4f..3975860331a6 100644
--- a/drivers/iio/accel/kxsd9.c
+++ b/drivers/iio/accel/kxsd9.c
@@ -476,7 +476,7 @@ err_power_down:
return ret;
}
-EXPORT_SYMBOL(kxsd9_common_probe);
+EXPORT_SYMBOL_NS(kxsd9_common_probe, IIO_KXSD9);
void kxsd9_common_remove(struct device *dev)
{
@@ -490,7 +490,7 @@ void kxsd9_common_remove(struct device *dev)
pm_runtime_disable(dev);
kxsd9_power_down(st);
}
-EXPORT_SYMBOL(kxsd9_common_remove);
+EXPORT_SYMBOL_NS(kxsd9_common_remove, IIO_KXSD9);
#ifdef CONFIG_PM
static int kxsd9_runtime_suspend(struct device *dev)
@@ -516,7 +516,7 @@ const struct dev_pm_ops kxsd9_dev_pm_ops = {
SET_RUNTIME_PM_OPS(kxsd9_runtime_suspend,
kxsd9_runtime_resume, NULL)
};
-EXPORT_SYMBOL(kxsd9_dev_pm_ops);
+EXPORT_SYMBOL_NS(kxsd9_dev_pm_ops, IIO_KXSD9);
MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
MODULE_DESCRIPTION("Kionix KXSD9 driver");
diff --git a/drivers/iio/accel/mc3230.c b/drivers/iio/accel/mc3230.c
index 735002b716f3..679e69cd7657 100644
--- a/drivers/iio/accel/mc3230.c
+++ b/drivers/iio/accel/mc3230.c
@@ -160,7 +160,6 @@ static int mc3230_remove(struct i2c_client *client)
return mc3230_set_opcon(iio_priv(indio_dev), MC3230_MODE_OPCON_STANDBY);
}
-#ifdef CONFIG_PM_SLEEP
static int mc3230_suspend(struct device *dev)
{
struct mc3230_data *data;
@@ -178,9 +177,8 @@ static int mc3230_resume(struct device *dev)
return mc3230_set_opcon(data, MC3230_MODE_OPCON_WAKE);
}
-#endif
-static SIMPLE_DEV_PM_OPS(mc3230_pm_ops, mc3230_suspend, mc3230_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(mc3230_pm_ops, mc3230_suspend, mc3230_resume);
static const struct i2c_device_id mc3230_i2c_id[] = {
{"mc3230", 0},
@@ -191,7 +189,7 @@ MODULE_DEVICE_TABLE(i2c, mc3230_i2c_id);
static struct i2c_driver mc3230_driver = {
.driver = {
.name = "mc3230",
- .pm = &mc3230_pm_ops,
+ .pm = pm_sleep_ptr(&mc3230_pm_ops),
},
.probe = mc3230_probe,
.remove = mc3230_remove,
diff --git a/drivers/iio/accel/mma7455_core.c b/drivers/iio/accel/mma7455_core.c
index e6739ba74edf..a34195b3215d 100644
--- a/drivers/iio/accel/mma7455_core.c
+++ b/drivers/iio/accel/mma7455_core.c
@@ -238,7 +238,7 @@ const struct regmap_config mma7455_core_regmap = {
.val_bits = 8,
.max_register = MMA7455_REG_TW,
};
-EXPORT_SYMBOL_GPL(mma7455_core_regmap);
+EXPORT_SYMBOL_NS_GPL(mma7455_core_regmap, IIO_MMA7455);
int mma7455_core_probe(struct device *dev, struct regmap *regmap,
const char *name)
@@ -293,7 +293,7 @@ int mma7455_core_probe(struct device *dev, struct regmap *regmap,
return 0;
}
-EXPORT_SYMBOL_GPL(mma7455_core_probe);
+EXPORT_SYMBOL_NS_GPL(mma7455_core_probe, IIO_MMA7455);
void mma7455_core_remove(struct device *dev)
{
@@ -306,7 +306,7 @@ void mma7455_core_remove(struct device *dev)
regmap_write(mma7455->regmap, MMA7455_REG_MCTL,
MMA7455_MCTL_MODE_STANDBY);
}
-EXPORT_SYMBOL_GPL(mma7455_core_remove);
+EXPORT_SYMBOL_NS_GPL(mma7455_core_remove, IIO_MMA7455);
MODULE_AUTHOR("Joachim Eastwood <manabian@gmail.com>");
MODULE_DESCRIPTION("Freescale MMA7455L core accelerometer driver");
diff --git a/drivers/iio/accel/mma7455_i2c.c b/drivers/iio/accel/mma7455_i2c.c
index 8a5256516f9f..a3b84e8a3ea8 100644
--- a/drivers/iio/accel/mma7455_i2c.c
+++ b/drivers/iio/accel/mma7455_i2c.c
@@ -61,3 +61,4 @@ module_i2c_driver(mma7455_i2c_driver);
MODULE_AUTHOR("Joachim Eastwood <manabian@gmail.com>");
MODULE_DESCRIPTION("Freescale MMA7455L I2C accelerometer driver");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS(IIO_MMA7455);
diff --git a/drivers/iio/accel/mma7455_spi.c b/drivers/iio/accel/mma7455_spi.c
index b746031551a3..fcdde2e8a84b 100644
--- a/drivers/iio/accel/mma7455_spi.c
+++ b/drivers/iio/accel/mma7455_spi.c
@@ -47,3 +47,4 @@ module_spi_driver(mma7455_spi_driver);
MODULE_AUTHOR("Joachim Eastwood <manabian@gmail.com>");
MODULE_DESCRIPTION("Freescale MMA7455L SPI accelerometer driver");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS(IIO_MMA7455);
diff --git a/drivers/iio/accel/mma7660.c b/drivers/iio/accel/mma7660.c
index 24b83ccdb950..112a5a33c29f 100644
--- a/drivers/iio/accel/mma7660.c
+++ b/drivers/iio/accel/mma7660.c
@@ -222,7 +222,6 @@ static int mma7660_remove(struct i2c_client *client)
return 0;
}
-#ifdef CONFIG_PM_SLEEP
static int mma7660_suspend(struct device *dev)
{
struct mma7660_data *data;
@@ -241,12 +240,8 @@ static int mma7660_resume(struct device *dev)
return mma7660_set_mode(data, MMA7660_MODE_ACTIVE);
}
-static SIMPLE_DEV_PM_OPS(mma7660_pm_ops, mma7660_suspend, mma7660_resume);
-
-#define MMA7660_PM_OPS (&mma7660_pm_ops)
-#else
-#define MMA7660_PM_OPS NULL
-#endif
+static DEFINE_SIMPLE_DEV_PM_OPS(mma7660_pm_ops, mma7660_suspend,
+ mma7660_resume);
static const struct i2c_device_id mma7660_i2c_id[] = {
{"mma7660", 0},
@@ -270,7 +265,7 @@ MODULE_DEVICE_TABLE(acpi, mma7660_acpi_id);
static struct i2c_driver mma7660_driver = {
.driver = {
.name = "mma7660",
- .pm = MMA7660_PM_OPS,
+ .pm = pm_sleep_ptr(&mma7660_pm_ops),
.of_match_table = mma7660_of_match,
.acpi_match_table = ACPI_PTR(mma7660_acpi_id),
},
diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c
index 64b82b4503ad..9c02c681c84c 100644
--- a/drivers/iio/accel/mma8452.c
+++ b/drivers/iio/accel/mma8452.c
@@ -104,6 +104,7 @@
struct mma8452_data {
struct i2c_client *client;
struct mutex lock;
+ struct iio_mount_matrix orientation;
u8 ctrl_reg1;
u8 data_cfg;
const struct mma_chip_info *chip_info;
@@ -176,6 +177,7 @@ static const struct mma8452_event_regs trans_ev_regs = {
* @enabled_events: event flags enabled and handled by this driver
*/
struct mma_chip_info {
+ const char *name;
u8 chip_id;
const struct iio_chan_spec *channels;
int num_channels;
@@ -379,8 +381,8 @@ static ssize_t mma8452_show_scale_avail(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- struct mma8452_data *data = iio_priv(i2c_get_clientdata(
- to_i2c_client(dev)));
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct mma8452_data *data = iio_priv(indio_dev);
return mma8452_show_int_plus_micros(buf, data->chip_info->mma_scales,
ARRAY_SIZE(data->chip_info->mma_scales));
@@ -1189,6 +1191,20 @@ static const struct attribute_group mma8452_event_attribute_group = {
.attrs = mma8452_event_attributes,
};
+static const struct iio_mount_matrix *
+mma8452_get_mount_matrix(const struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan)
+{
+ struct mma8452_data *data = iio_priv(indio_dev);
+
+ return &data->orientation;
+}
+
+static const struct iio_chan_spec_ext_info mma8452_ext_info[] = {
+ IIO_MOUNT_MATRIX(IIO_SHARED_BY_TYPE, mma8452_get_mount_matrix),
+ { }
+};
+
#define MMA8452_FREEFALL_CHANNEL(modifier) { \
.type = IIO_ACCEL, \
.modified = 1, \
@@ -1227,6 +1243,7 @@ static const struct attribute_group mma8452_event_attribute_group = {
}, \
.event_spec = mma8452_transient_event, \
.num_event_specs = ARRAY_SIZE(mma8452_transient_event), \
+ .ext_info = mma8452_ext_info, \
}
#define MMA8652_CHANNEL(axis, idx, bits) { \
@@ -1248,6 +1265,7 @@ static const struct attribute_group mma8452_event_attribute_group = {
}, \
.event_spec = mma8452_motion_event, \
.num_event_specs = ARRAY_SIZE(mma8452_motion_event), \
+ .ext_info = mma8452_ext_info, \
}
static const struct iio_chan_spec mma8451_channels[] = {
@@ -1301,6 +1319,7 @@ enum {
static const struct mma_chip_info mma_chip_info_table[] = {
[mma8451] = {
+ .name = "mma8451",
.chip_id = MMA8451_DEVICE_ID,
.channels = mma8451_channels,
.num_channels = ARRAY_SIZE(mma8451_channels),
@@ -1325,6 +1344,7 @@ static const struct mma_chip_info mma_chip_info_table[] = {
MMA8452_INT_FF_MT,
},
[mma8452] = {
+ .name = "mma8452",
.chip_id = MMA8452_DEVICE_ID,
.channels = mma8452_channels,
.num_channels = ARRAY_SIZE(mma8452_channels),
@@ -1341,6 +1361,7 @@ static const struct mma_chip_info mma_chip_info_table[] = {
MMA8452_INT_FF_MT,
},
[mma8453] = {
+ .name = "mma8453",
.chip_id = MMA8453_DEVICE_ID,
.channels = mma8453_channels,
.num_channels = ARRAY_SIZE(mma8453_channels),
@@ -1357,6 +1378,7 @@ static const struct mma_chip_info mma_chip_info_table[] = {
MMA8452_INT_FF_MT,
},
[mma8652] = {
+ .name = "mma8652",
.chip_id = MMA8652_DEVICE_ID,
.channels = mma8652_channels,
.num_channels = ARRAY_SIZE(mma8652_channels),
@@ -1366,6 +1388,7 @@ static const struct mma_chip_info mma_chip_info_table[] = {
.enabled_events = MMA8452_INT_FF_MT,
},
[mma8653] = {
+ .name = "mma8653",
.chip_id = MMA8653_DEVICE_ID,
.channels = mma8653_channels,
.num_channels = ARRAY_SIZE(mma8653_channels),
@@ -1380,6 +1403,7 @@ static const struct mma_chip_info mma_chip_info_table[] = {
.enabled_events = MMA8452_INT_FF_MT,
},
[fxls8471] = {
+ .name = "fxls8471",
.chip_id = FXLS8471_DEVICE_ID,
.channels = mma8451_channels,
.num_channels = ARRAY_SIZE(mma8451_channels),
@@ -1522,13 +1546,6 @@ static int mma8452_probe(struct i2c_client *client,
struct mma8452_data *data;
struct iio_dev *indio_dev;
int ret;
- const struct of_device_id *match;
-
- match = of_match_device(mma8452_dt_ids, &client->dev);
- if (!match) {
- dev_err(&client->dev, "unknown device model\n");
- return -ENODEV;
- }
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
if (!indio_dev)
@@ -1537,7 +1554,18 @@ static int mma8452_probe(struct i2c_client *client,
data = iio_priv(indio_dev);
data->client = client;
mutex_init(&data->lock);
- data->chip_info = match->data;
+
+ data->chip_info = device_get_match_data(&client->dev);
+ if (!data->chip_info && id) {
+ data->chip_info = &mma_chip_info_table[id->driver_data];
+ } else {
+ dev_err(&client->dev, "unknown device model\n");
+ return -ENODEV;
+ }
+
+ ret = iio_read_mount_matrix(&client->dev, &data->orientation);
+ if (ret)
+ return ret;
data->vdd_reg = devm_regulator_get(&client->dev, "vdd");
if (IS_ERR(data->vdd_reg))
@@ -1581,11 +1609,11 @@ static int mma8452_probe(struct i2c_client *client,
}
dev_info(&client->dev, "registering %s accelerometer; ID 0x%x\n",
- match->compatible, data->chip_info->chip_id);
+ data->chip_info->name, data->chip_info->chip_id);
i2c_set_clientdata(client, indio_dev);
indio_dev->info = &mma8452_info;
- indio_dev->name = id->name;
+ indio_dev->name = data->chip_info->name;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = data->chip_info->channels;
indio_dev->num_channels = data->chip_info->num_channels;
@@ -1810,7 +1838,7 @@ MODULE_DEVICE_TABLE(i2c, mma8452_id);
static struct i2c_driver mma8452_driver = {
.driver = {
.name = "mma8452",
- .of_match_table = of_match_ptr(mma8452_dt_ids),
+ .of_match_table = mma8452_dt_ids,
.pm = &mma8452_pm_ops,
},
.probe = mma8452_probe,
diff --git a/drivers/iio/accel/mma9551.c b/drivers/iio/accel/mma9551.c
index c53a3398b14c..123cdbbb265c 100644
--- a/drivers/iio/accel/mma9551.c
+++ b/drivers/iio/accel/mma9551.c
@@ -526,7 +526,6 @@ static int mma9551_remove(struct i2c_client *client)
return 0;
}
-#ifdef CONFIG_PM
static int mma9551_runtime_suspend(struct device *dev)
{
struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
@@ -558,9 +557,7 @@ static int mma9551_runtime_resume(struct device *dev)
return 0;
}
-#endif
-#ifdef CONFIG_PM_SLEEP
static int mma9551_suspend(struct device *dev)
{
struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
@@ -586,12 +583,10 @@ static int mma9551_resume(struct device *dev)
return ret;
}
-#endif
static const struct dev_pm_ops mma9551_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(mma9551_suspend, mma9551_resume)
- SET_RUNTIME_PM_OPS(mma9551_runtime_suspend,
- mma9551_runtime_resume, NULL)
+ SYSTEM_SLEEP_PM_OPS(mma9551_suspend, mma9551_resume)
+ RUNTIME_PM_OPS(mma9551_runtime_suspend, mma9551_runtime_resume, NULL)
};
static const struct acpi_device_id mma9551_acpi_match[] = {
@@ -612,7 +607,7 @@ static struct i2c_driver mma9551_driver = {
.driver = {
.name = MMA9551_DRV_NAME,
.acpi_match_table = ACPI_PTR(mma9551_acpi_match),
- .pm = &mma9551_pm_ops,
+ .pm = pm_ptr(&mma9551_pm_ops),
},
.probe = mma9551_probe,
.remove = mma9551_remove,
@@ -625,3 +620,4 @@ MODULE_AUTHOR("Irina Tirdea <irina.tirdea@intel.com>");
MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("MMA9551L motion-sensing platform driver");
+MODULE_IMPORT_NS(IIO_MMA9551);
diff --git a/drivers/iio/accel/mma9551_core.c b/drivers/iio/accel/mma9551_core.c
index fbf2e2c45678..64ca7d7a9673 100644
--- a/drivers/iio/accel/mma9551_core.c
+++ b/drivers/iio/accel/mma9551_core.c
@@ -219,7 +219,7 @@ int mma9551_read_config_byte(struct i2c_client *client, u8 app_id,
return mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG,
reg, NULL, 0, val, 1);
}
-EXPORT_SYMBOL(mma9551_read_config_byte);
+EXPORT_SYMBOL_NS(mma9551_read_config_byte, IIO_MMA9551);
/**
* mma9551_write_config_byte() - write 1 configuration byte
@@ -244,7 +244,7 @@ int mma9551_write_config_byte(struct i2c_client *client, u8 app_id,
return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG, reg,
&val, 1, NULL, 0);
}
-EXPORT_SYMBOL(mma9551_write_config_byte);
+EXPORT_SYMBOL_NS(mma9551_write_config_byte, IIO_MMA9551);
/**
* mma9551_read_status_byte() - read 1 status byte
@@ -269,7 +269,7 @@ int mma9551_read_status_byte(struct i2c_client *client, u8 app_id,
return mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS,
reg, NULL, 0, val, 1);
}
-EXPORT_SYMBOL(mma9551_read_status_byte);
+EXPORT_SYMBOL_NS(mma9551_read_status_byte, IIO_MMA9551);
/**
* mma9551_read_config_word() - read 1 config word
@@ -300,7 +300,7 @@ int mma9551_read_config_word(struct i2c_client *client, u8 app_id,
return ret;
}
-EXPORT_SYMBOL(mma9551_read_config_word);
+EXPORT_SYMBOL_NS(mma9551_read_config_word, IIO_MMA9551);
/**
* mma9551_write_config_word() - write 1 config word
@@ -327,7 +327,7 @@ int mma9551_write_config_word(struct i2c_client *client, u8 app_id,
return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG, reg,
(u8 *)&v, 2, NULL, 0);
}
-EXPORT_SYMBOL(mma9551_write_config_word);
+EXPORT_SYMBOL_NS(mma9551_write_config_word, IIO_MMA9551);
/**
* mma9551_read_status_word() - read 1 status word
@@ -358,7 +358,7 @@ int mma9551_read_status_word(struct i2c_client *client, u8 app_id,
return ret;
}
-EXPORT_SYMBOL(mma9551_read_status_word);
+EXPORT_SYMBOL_NS(mma9551_read_status_word, IIO_MMA9551);
/**
* mma9551_read_config_words() - read multiple config words
@@ -397,7 +397,7 @@ int mma9551_read_config_words(struct i2c_client *client, u8 app_id,
return 0;
}
-EXPORT_SYMBOL(mma9551_read_config_words);
+EXPORT_SYMBOL_NS(mma9551_read_config_words, IIO_MMA9551);
/**
* mma9551_read_status_words() - read multiple status words
@@ -436,7 +436,7 @@ int mma9551_read_status_words(struct i2c_client *client, u8 app_id,
return 0;
}
-EXPORT_SYMBOL(mma9551_read_status_words);
+EXPORT_SYMBOL_NS(mma9551_read_status_words, IIO_MMA9551);
/**
* mma9551_write_config_words() - write multiple config words
@@ -471,7 +471,7 @@ int mma9551_write_config_words(struct i2c_client *client, u8 app_id,
return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG,
reg, (u8 *)be_buf, len * sizeof(u16), NULL, 0);
}
-EXPORT_SYMBOL(mma9551_write_config_words);
+EXPORT_SYMBOL_NS(mma9551_write_config_words, IIO_MMA9551);
/**
* mma9551_update_config_bits() - update bits in register
@@ -507,7 +507,7 @@ int mma9551_update_config_bits(struct i2c_client *client, u8 app_id,
return mma9551_write_config_byte(client, app_id, reg, tmp);
}
-EXPORT_SYMBOL(mma9551_update_config_bits);
+EXPORT_SYMBOL_NS(mma9551_update_config_bits, IIO_MMA9551);
/**
* mma9551_gpio_config() - configure gpio
@@ -586,7 +586,7 @@ int mma9551_gpio_config(struct i2c_client *client, enum mma9551_gpio_pin pin,
return ret;
}
-EXPORT_SYMBOL(mma9551_gpio_config);
+EXPORT_SYMBOL_NS(mma9551_gpio_config, IIO_MMA9551);
/**
* mma9551_read_version() - read device version information
@@ -616,7 +616,7 @@ int mma9551_read_version(struct i2c_client *client)
return 0;
}
-EXPORT_SYMBOL(mma9551_read_version);
+EXPORT_SYMBOL_NS(mma9551_read_version, IIO_MMA9551);
/**
* mma9551_set_device_state() - sets HW power mode
@@ -646,7 +646,7 @@ int mma9551_set_device_state(struct i2c_client *client, bool enable)
MMA9551_SLEEP_CFG_FLEEN :
MMA9551_SLEEP_CFG_SNCEN);
}
-EXPORT_SYMBOL(mma9551_set_device_state);
+EXPORT_SYMBOL_NS(mma9551_set_device_state, IIO_MMA9551);
/**
* mma9551_set_power_state() - sets runtime PM state
@@ -680,7 +680,7 @@ int mma9551_set_power_state(struct i2c_client *client, bool on)
return 0;
}
-EXPORT_SYMBOL(mma9551_set_power_state);
+EXPORT_SYMBOL_NS(mma9551_set_power_state, IIO_MMA9551);
/**
* mma9551_sleep() - sleep
@@ -699,7 +699,7 @@ void mma9551_sleep(int freq)
else
msleep_interruptible(sleep_val);
}
-EXPORT_SYMBOL(mma9551_sleep);
+EXPORT_SYMBOL_NS(mma9551_sleep, IIO_MMA9551);
/**
* mma9551_read_accel_chan() - read accelerometer channel
@@ -755,7 +755,7 @@ out_poweroff:
mma9551_set_power_state(client, false);
return ret;
}
-EXPORT_SYMBOL(mma9551_read_accel_chan);
+EXPORT_SYMBOL_NS(mma9551_read_accel_chan, IIO_MMA9551);
/**
* mma9551_read_accel_scale() - read accelerometer scale
@@ -773,7 +773,7 @@ int mma9551_read_accel_scale(int *val, int *val2)
return IIO_VAL_INT_PLUS_MICRO;
}
-EXPORT_SYMBOL(mma9551_read_accel_scale);
+EXPORT_SYMBOL_NS(mma9551_read_accel_scale, IIO_MMA9551);
/**
* mma9551_app_reset() - reset application
@@ -792,7 +792,7 @@ int mma9551_app_reset(struct i2c_client *client, u32 app_mask)
MMA9551_RSC_OFFSET(app_mask),
MMA9551_RSC_VAL(app_mask));
}
-EXPORT_SYMBOL(mma9551_app_reset);
+EXPORT_SYMBOL_NS(mma9551_app_reset, IIO_MMA9551);
MODULE_AUTHOR("Irina Tirdea <irina.tirdea@intel.com>");
MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>");
diff --git a/drivers/iio/accel/mma9553.c b/drivers/iio/accel/mma9553.c
index 5ff6bc70708b..09df58d4be33 100644
--- a/drivers/iio/accel/mma9553.c
+++ b/drivers/iio/accel/mma9553.c
@@ -1165,7 +1165,6 @@ static int mma9553_remove(struct i2c_client *client)
return 0;
}
-#ifdef CONFIG_PM
static int mma9553_runtime_suspend(struct device *dev)
{
struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
@@ -1197,9 +1196,7 @@ static int mma9553_runtime_resume(struct device *dev)
return 0;
}
-#endif
-#ifdef CONFIG_PM_SLEEP
static int mma9553_suspend(struct device *dev)
{
struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
@@ -1225,12 +1222,10 @@ static int mma9553_resume(struct device *dev)
return ret;
}
-#endif
static const struct dev_pm_ops mma9553_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(mma9553_suspend, mma9553_resume)
- SET_RUNTIME_PM_OPS(mma9553_runtime_suspend,
- mma9553_runtime_resume, NULL)
+ SYSTEM_SLEEP_PM_OPS(mma9553_suspend, mma9553_resume)
+ RUNTIME_PM_OPS(mma9553_runtime_suspend, mma9553_runtime_resume, NULL)
};
static const struct acpi_device_id mma9553_acpi_match[] = {
@@ -1251,7 +1246,7 @@ static struct i2c_driver mma9553_driver = {
.driver = {
.name = MMA9553_DRV_NAME,
.acpi_match_table = ACPI_PTR(mma9553_acpi_match),
- .pm = &mma9553_pm_ops,
+ .pm = pm_ptr(&mma9553_pm_ops),
},
.probe = mma9553_probe,
.remove = mma9553_remove,
@@ -1263,3 +1258,4 @@ module_i2c_driver(mma9553_driver);
MODULE_AUTHOR("Irina Tirdea <irina.tirdea@intel.com>");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("MMA9553L pedometer platform driver");
+MODULE_IMPORT_NS(IIO_MMA9551);
diff --git a/drivers/iio/accel/ssp_accel_sensor.c b/drivers/iio/accel/ssp_accel_sensor.c
index 04dcb2b657ee..a1164b439f41 100644
--- a/drivers/iio/accel/ssp_accel_sensor.c
+++ b/drivers/iio/accel/ssp_accel_sensor.c
@@ -142,3 +142,4 @@ module_platform_driver(ssp_accel_driver);
MODULE_AUTHOR("Karol Wrona <k.wrona@samsung.com>");
MODULE_DESCRIPTION("Samsung sensorhub accelerometers driver");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(IIO_SSP_SENSORS);
diff --git a/drivers/iio/accel/st_accel.h b/drivers/iio/accel/st_accel.h
index 8750dea56fcb..00e056c21bfc 100644
--- a/drivers/iio/accel/st_accel.h
+++ b/drivers/iio/accel/st_accel.h
@@ -36,6 +36,7 @@ enum st_accel_type {
LIS3DHH,
LIS2DE12,
LIS2HH12,
+ SC7A20,
ST_ACCEL_MAX,
};
@@ -61,6 +62,7 @@ enum st_accel_type {
#define LIS3DE_ACCEL_DEV_NAME "lis3de"
#define LIS2DE12_ACCEL_DEV_NAME "lis2de12"
#define LIS2HH12_ACCEL_DEV_NAME "lis2hh12"
+#define SC7A20_ACCEL_DEV_NAME "sc7a20"
#ifdef CONFIG_IIO_BUFFER
int st_accel_allocate_ring(struct iio_dev *indio_dev);
diff --git a/drivers/iio/accel/st_accel_buffer.c b/drivers/iio/accel/st_accel_buffer.c
index fc82fa83f1fb..b2977ae19b69 100644
--- a/drivers/iio/accel/st_accel_buffer.c
+++ b/drivers/iio/accel/st_accel_buffer.c
@@ -7,7 +7,6 @@
* Denis Ciocca <denis.ciocca@st.com>
*/
-#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
@@ -65,7 +64,3 @@ int st_accel_allocate_ring(struct iio_dev *indio_dev)
return devm_iio_triggered_buffer_setup(indio_dev->dev.parent, indio_dev,
NULL, &st_sensors_trigger_handler, &st_accel_buffer_setup_ops);
}
-
-MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
-MODULE_DESCRIPTION("STMicroelectronics accelerometers buffer");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c
index 31ea19d0ba71..5c5da6fdb490 100644
--- a/drivers/iio/accel/st_accel_core.c
+++ b/drivers/iio/accel/st_accel_core.c
@@ -1087,6 +1087,89 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
.multi_read_bit = true,
.bootime = 2,
},
+ {
+ /*
+ * Not an ST part. Register-compatible with the LIS2DH, even
+ * though the WAI value is different.
+ */
+ .wai = 0x11,
+ .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
+ .sensors_supported = {
+ [0] = SC7A20_ACCEL_DEV_NAME,
+ },
+ .ch = (struct iio_chan_spec *)st_accel_12bit_channels,
+ .odr = {
+ .addr = 0x20,
+ .mask = 0xf0,
+ .odr_avl = {
+ { .hz = 1, .value = 0x01, },
+ { .hz = 10, .value = 0x02, },
+ { .hz = 25, .value = 0x03, },
+ { .hz = 50, .value = 0x04, },
+ { .hz = 100, .value = 0x05, },
+ { .hz = 200, .value = 0x06, },
+ { .hz = 400, .value = 0x07, },
+ { .hz = 1600, .value = 0x08, },
+ },
+ },
+ .pw = {
+ .addr = 0x20,
+ .mask = 0xf0,
+ .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
+ },
+ .enable_axis = {
+ .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
+ .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
+ },
+ .fs = {
+ .addr = 0x23,
+ .mask = 0x30,
+ .fs_avl = {
+ [0] = {
+ .num = ST_ACCEL_FS_AVL_2G,
+ .value = 0x00,
+ .gain = IIO_G_TO_M_S_2(1000),
+ },
+ [1] = {
+ .num = ST_ACCEL_FS_AVL_4G,
+ .value = 0x01,
+ .gain = IIO_G_TO_M_S_2(2000),
+ },
+ [2] = {
+ .num = ST_ACCEL_FS_AVL_8G,
+ .value = 0x02,
+ .gain = IIO_G_TO_M_S_2(4000),
+ },
+ [3] = {
+ .num = ST_ACCEL_FS_AVL_16G,
+ .value = 0x03,
+ .gain = IIO_G_TO_M_S_2(12000),
+ },
+ },
+ },
+ .bdu = {
+ .addr = 0x23,
+ .mask = 0x80,
+ },
+ .drdy_irq = {
+ .int1 = {
+ .addr = 0x22,
+ .mask = 0x10,
+ },
+ .addr_ihl = 0x25,
+ .mask_ihl = 0x02,
+ .stat_drdy = {
+ .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
+ .mask = 0x07,
+ },
+ },
+ .sim = {
+ .addr = 0x23,
+ .value = BIT(0),
+ },
+ .multi_read_bit = true,
+ .bootime = 2,
+ },
};
/* Default accel DRDY is available on INT1 pin */
@@ -1329,7 +1412,7 @@ const struct st_sensor_settings *st_accel_get_settings(const char *name)
return &st_accel_sensors_settings[index];
}
-EXPORT_SYMBOL(st_accel_get_settings);
+EXPORT_SYMBOL_NS(st_accel_get_settings, IIO_ST_SENSORS);
int st_accel_common_probe(struct iio_dev *indio_dev)
{
@@ -1383,8 +1466,9 @@ int st_accel_common_probe(struct iio_dev *indio_dev)
return devm_iio_device_register(parent, indio_dev);
}
-EXPORT_SYMBOL(st_accel_common_probe);
+EXPORT_SYMBOL_NS(st_accel_common_probe, IIO_ST_SENSORS);
MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
MODULE_DESCRIPTION("STMicroelectronics accelerometers driver");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS(IIO_ST_SENSORS);
diff --git a/drivers/iio/accel/st_accel_i2c.c b/drivers/iio/accel/st_accel_i2c.c
index c0ce78eebad9..96adc4344f4a 100644
--- a/drivers/iio/accel/st_accel_i2c.c
+++ b/drivers/iio/accel/st_accel_i2c.c
@@ -107,6 +107,10 @@ static const struct of_device_id st_accel_of_match[] = {
.compatible = "st,lis2hh12",
.data = LIS2HH12_ACCEL_DEV_NAME,
},
+ {
+ .compatible = "silan,sc7a20",
+ .data = SC7A20_ACCEL_DEV_NAME,
+ },
{},
};
MODULE_DEVICE_TABLE(of, st_accel_of_match);
@@ -142,6 +146,7 @@ static const struct i2c_device_id st_accel_id_table[] = {
{ LIS3DE_ACCEL_DEV_NAME },
{ LIS2DE12_ACCEL_DEV_NAME },
{ LIS2HH12_ACCEL_DEV_NAME },
+ { SC7A20_ACCEL_DEV_NAME },
{},
};
MODULE_DEVICE_TABLE(i2c, st_accel_id_table);
@@ -194,3 +199,4 @@ module_i2c_driver(st_accel_driver);
MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
MODULE_DESCRIPTION("STMicroelectronics accelerometers i2c driver");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS(IIO_ST_SENSORS);
diff --git a/drivers/iio/accel/st_accel_spi.c b/drivers/iio/accel/st_accel_spi.c
index b74a1c6d03de..108b63d0146c 100644
--- a/drivers/iio/accel/st_accel_spi.c
+++ b/drivers/iio/accel/st_accel_spi.c
@@ -164,3 +164,4 @@ module_spi_driver(st_accel_driver);
MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
MODULE_DESCRIPTION("STMicroelectronics accelerometers spi driver");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS(IIO_ST_SENSORS);
diff --git a/drivers/iio/accel/stk8312.c b/drivers/iio/accel/stk8312.c
index de0cdf8c1f94..a71dfff3ca4a 100644
--- a/drivers/iio/accel/stk8312.c
+++ b/drivers/iio/accel/stk8312.c
@@ -611,7 +611,6 @@ static int stk8312_remove(struct i2c_client *client)
return stk8312_set_mode(data, STK8312_MODE_STANDBY);
}
-#ifdef CONFIG_PM_SLEEP
static int stk8312_suspend(struct device *dev)
{
struct stk8312_data *data;
@@ -630,12 +629,8 @@ static int stk8312_resume(struct device *dev)
return stk8312_set_mode(data, data->mode | STK8312_MODE_ACTIVE);
}
-static SIMPLE_DEV_PM_OPS(stk8312_pm_ops, stk8312_suspend, stk8312_resume);
-
-#define STK8312_PM_OPS (&stk8312_pm_ops)
-#else
-#define STK8312_PM_OPS NULL
-#endif
+static DEFINE_SIMPLE_DEV_PM_OPS(stk8312_pm_ops, stk8312_suspend,
+ stk8312_resume);
static const struct i2c_device_id stk8312_i2c_id[] = {
/* Deprecated in favour of lowercase form */
@@ -648,7 +643,7 @@ MODULE_DEVICE_TABLE(i2c, stk8312_i2c_id);
static struct i2c_driver stk8312_driver = {
.driver = {
.name = STK8312_DRIVER_NAME,
- .pm = STK8312_PM_OPS,
+ .pm = pm_sleep_ptr(&stk8312_pm_ops),
},
.probe = stk8312_probe,
.remove = stk8312_remove,
diff --git a/drivers/iio/accel/stk8ba50.c b/drivers/iio/accel/stk8ba50.c
index 517c57ed9e94..0067ec5cbae8 100644
--- a/drivers/iio/accel/stk8ba50.c
+++ b/drivers/iio/accel/stk8ba50.c
@@ -504,7 +504,6 @@ static int stk8ba50_remove(struct i2c_client *client)
return stk8ba50_set_power(data, STK8BA50_MODE_SUSPEND);
}
-#ifdef CONFIG_PM_SLEEP
static int stk8ba50_suspend(struct device *dev)
{
struct stk8ba50_data *data;
@@ -523,12 +522,8 @@ static int stk8ba50_resume(struct device *dev)
return stk8ba50_set_power(data, STK8BA50_MODE_NORMAL);
}
-static SIMPLE_DEV_PM_OPS(stk8ba50_pm_ops, stk8ba50_suspend, stk8ba50_resume);
-
-#define STK8BA50_PM_OPS (&stk8ba50_pm_ops)
-#else
-#define STK8BA50_PM_OPS NULL
-#endif
+static DEFINE_SIMPLE_DEV_PM_OPS(stk8ba50_pm_ops, stk8ba50_suspend,
+ stk8ba50_resume);
static const struct i2c_device_id stk8ba50_i2c_id[] = {
{"stk8ba50", 0},
@@ -546,7 +541,7 @@ MODULE_DEVICE_TABLE(acpi, stk8ba50_acpi_id);
static struct i2c_driver stk8ba50_driver = {
.driver = {
.name = "stk8ba50",
- .pm = STK8BA50_PM_OPS,
+ .pm = pm_sleep_ptr(&stk8ba50_pm_ops),
.acpi_match_table = ACPI_PTR(stk8ba50_acpi_id),
},
.probe = stk8ba50_probe,