diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2017-11-23 16:29:05 +0100 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2017-11-23 16:29:05 +0100 |
commit | 866c9b94ef968445c52214b3748ecc52a8491bca (patch) | |
tree | 1fd073acb9be8e89e77b35c41e2964ac6feabee6 /drivers/iio | |
parent | aea3706cfc4d952ed6d32b6d5845b5ecd99ed7f5 (diff) | |
parent | 841b86f3289dbe858daeceec36423d4ea286fac2 (diff) | |
download | linux-stable-866c9b94ef968445c52214b3748ecc52a8491bca.tar.gz linux-stable-866c9b94ef968445c52214b3748ecc52a8491bca.tar.bz2 linux-stable-866c9b94ef968445c52214b3748ecc52a8491bca.zip |
Merge tag 'for-linus-timers-conversion-final-v4.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux into timers/urgent
Pull the last batch of manual timer conversions from Kees Cook:
- final batch of "non trivial" timer conversions (multi-tree dependencies,
things Coccinelle couldn't handle, etc).
- treewide conversions via Coccinelle, in 4 steps:
- DEFINE_TIMER() functions converted to struct timer_list * argument
- init_timer() -> setup_timer()
- setup_timer() -> timer_setup()
- setup_timer() -> timer_setup() (with a single embedded structure)
- deprecated timer API removals (init_timer(), setup_*timer())
- finalization of new API (remove global casts)
Diffstat (limited to 'drivers/iio')
285 files changed, 3240 insertions, 1104 deletions
diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig index 15de262015df..c6d9517d7611 100644 --- a/drivers/iio/accel/Kconfig +++ b/drivers/iio/accel/Kconfig @@ -148,6 +148,17 @@ config HID_SENSOR_ACCEL_3D To compile this driver as a module, choose M here: the module will be called hid-sensor-accel-3d. +config IIO_CROS_EC_ACCEL_LEGACY + tristate "ChromeOS EC Legacy Accelerometer Sensor" + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + select CROS_EC_LPC_REGISTER_DEVICE + help + Say yes here to get support for accelerometers on Chromebook using + legacy EC firmware. + Sensor data is retrieved through IO memory. + Newer devices should use IIO_CROS_EC_SENSORS. + config IIO_ST_ACCEL_3AXIS tristate "STMicroelectronics accelerometers 3-Axis Driver" depends on (I2C || SPI_MASTER) && SYSFS @@ -219,8 +230,8 @@ config KXCJK1013 select IIO_TRIGGERED_BUFFER help Say Y here if you want to build a driver for the Kionix KXCJK-1013 - triaxial acceleration sensor. This driver also supports KXCJ9-1008 - and KXTJ2-1009. + triaxial acceleration sensor. This driver also supports KXCJ9-1008, + KXTJ2-1009 and KXTF9. To compile this driver as a module, choose M here: the module will be called kxcjk-1013. diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile index 703e7c21f547..368aedb6377a 100644 --- a/drivers/iio/accel/Makefile +++ b/drivers/iio/accel/Makefile @@ -44,6 +44,8 @@ obj-$(CONFIG_SCA3000) += sca3000.o obj-$(CONFIG_STK8312) += stk8312.o obj-$(CONFIG_STK8BA50) += stk8ba50.o +obj-$(CONFIG_IIO_CROS_EC_ACCEL_LEGACY) += cros_ec_accel_legacy.o + obj-$(CONFIG_IIO_SSP_SENSORS_COMMONS) += ssp_accel_sensor.o obj-$(CONFIG_IIO_ST_ACCEL_3AXIS) += st_accel.o diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index 9ccb5828db98..7251d0e63d74 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -95,7 +95,6 @@ static int adxl345_read_raw(struct iio_dev *indio_dev, } static const struct iio_info adxl345_info = { - .driver_module = THIS_MODULE, .read_raw = adxl345_read_raw, }; diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c index 3dec972ca672..cb9765a3de60 100644 --- a/drivers/iio/accel/bma180.c +++ b/drivers/iio/accel/bma180.c @@ -536,7 +536,6 @@ static const struct iio_info bma180_info = { .attrs = &bma180_attrs_group, .read_raw = bma180_read_raw, .write_raw = bma180_write_raw, - .driver_module = THIS_MODULE, }; static const char * const bma180_power_modes[] = { "low_noise", "low_power" }; @@ -700,7 +699,6 @@ static int bma180_trig_try_reen(struct iio_trigger *trig) static const struct iio_trigger_ops bma180_trigger_ops = { .set_trigger_state = bma180_data_rdy_trigger_set_state, .try_reenable = bma180_trig_try_reen, - .owner = THIS_MODULE, }; static int bma180_probe(struct i2c_client *client, diff --git a/drivers/iio/accel/bma220_spi.c b/drivers/iio/accel/bma220_spi.c index 5099f295dd37..e25d91c017ed 100644 --- a/drivers/iio/accel/bma220_spi.c +++ b/drivers/iio/accel/bma220_spi.c @@ -186,7 +186,6 @@ static int bma220_write_raw(struct iio_dev *indio_dev, } static const struct iio_info bma220_info = { - .driver_module = THIS_MODULE, .read_raw = bma220_read_raw, .write_raw = bma220_write_raw, .attrs = &bma220_attribute_group, diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c index 807299dd45eb..870f92ef61c2 100644 --- a/drivers/iio/accel/bmc150-accel-core.c +++ b/drivers/iio/accel/bmc150-accel-core.c @@ -1094,7 +1094,6 @@ static const struct iio_info bmc150_accel_info = { .write_event_value = bmc150_accel_write_event, .write_event_config = bmc150_accel_write_event_config, .read_event_config = bmc150_accel_read_event_config, - .driver_module = THIS_MODULE, }; static const struct iio_info bmc150_accel_info_fifo = { @@ -1108,7 +1107,6 @@ static const struct iio_info bmc150_accel_info_fifo = { .validate_trigger = bmc150_accel_validate_trigger, .hwfifo_set_watermark = bmc150_accel_set_watermark, .hwfifo_flush_to_buffer = bmc150_accel_fifo_flush, - .driver_module = THIS_MODULE, }; static const unsigned long bmc150_accel_scan_masks[] = { @@ -1200,7 +1198,6 @@ static int bmc150_accel_trigger_set_state(struct iio_trigger *trig, static const struct iio_trigger_ops bmc150_accel_trigger_ops = { .set_trigger_state = bmc150_accel_trigger_set_state, .try_reenable = bmc150_accel_trig_try_reen, - .owner = THIS_MODULE, }; static int bmc150_accel_handle_roc_event(struct iio_dev *indio_dev) diff --git a/drivers/iio/accel/cros_ec_accel_legacy.c b/drivers/iio/accel/cros_ec_accel_legacy.c new file mode 100644 index 000000000000..063e89eff791 --- /dev/null +++ b/drivers/iio/accel/cros_ec_accel_legacy.c @@ -0,0 +1,423 @@ +/* + * Driver for older Chrome OS EC accelerometer + * + * Copyright 2017 Google, Inc + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * This driver uses the memory mapper cros-ec interface to communicate + * with the Chrome OS EC about accelerometer data. + * Accelerometer access is presented through iio sysfs. + */ + +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/iio/buffer.h> +#include <linux/iio/iio.h> +#include <linux/iio/kfifo_buf.h> +#include <linux/iio/trigger_consumer.h> +#include <linux/iio/triggered_buffer.h> +#include <linux/kernel.h> +#include <linux/mfd/cros_ec.h> +#include <linux/mfd/cros_ec_commands.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/sysfs.h> +#include <linux/platform_device.h> + +#define DRV_NAME "cros-ec-accel-legacy" + +/* + * Sensor scale hard coded at 10 bits per g, computed as: + * g / (2^10 - 1) = 0.009586168; with g = 9.80665 m.s^-2 + */ +#define ACCEL_LEGACY_NSCALE 9586168 + +/* Indices for EC sensor values. */ +enum { + X, + Y, + Z, + MAX_AXIS, +}; + +/* State data for cros_ec_accel_legacy iio driver. */ +struct cros_ec_accel_legacy_state { + struct cros_ec_device *ec; + + /* + * Array holding data from a single capture. 2 bytes per channel + * for the 3 channels plus the timestamp which is always last and + * 8-bytes aligned. + */ + s16 capture_data[8]; + s8 sign[MAX_AXIS]; + u8 sensor_num; +}; + +static int ec_cmd_read_u8(struct cros_ec_device *ec, unsigned int offset, + u8 *dest) +{ + return ec->cmd_readmem(ec, offset, 1, dest); +} + +static int ec_cmd_read_u16(struct cros_ec_device *ec, unsigned int offset, + u16 *dest) +{ + __le16 tmp; + int ret = ec->cmd_readmem(ec, offset, 2, &tmp); + + *dest = le16_to_cpu(tmp); + + return ret; +} + +/** + * read_ec_until_not_busy() - Read from EC status byte until it reads not busy. + * @st: Pointer to state information for device. + * + * This function reads EC status until its busy bit gets cleared. It does not + * wait indefinitely and returns -EIO if the EC status is still busy after a + * few hundreds milliseconds. + * + * Return: 8-bit status if ok, -EIO on error + */ +static int read_ec_until_not_busy(struct cros_ec_accel_legacy_state *st) +{ + struct cros_ec_device *ec = st->ec; + u8 status; + int attempts = 0; + + ec_cmd_read_u8(ec, EC_MEMMAP_ACC_STATUS, &status); + while (status & EC_MEMMAP_ACC_STATUS_BUSY_BIT) { + /* Give up after enough attempts, return error. */ + if (attempts++ >= 50) + return -EIO; + + /* Small delay every so often. */ + if (attempts % 5 == 0) + msleep(25); + + ec_cmd_read_u8(ec, EC_MEMMAP_ACC_STATUS, &status); + } + + return status; +} + +/** + * read_ec_accel_data_unsafe() - Read acceleration data from EC shared memory. + * @st: Pointer to state information for device. + * @scan_mask: Bitmap of the sensor indices to scan. + * @data: Location to store data. + * + * This is the unsafe function for reading the EC data. It does not guarantee + * that the EC will not modify the data as it is being read in. + */ +static void read_ec_accel_data_unsafe(struct cros_ec_accel_legacy_state *st, + unsigned long scan_mask, s16 *data) +{ + int i = 0; + int num_enabled = bitmap_weight(&scan_mask, MAX_AXIS); + + /* Read all sensors enabled in scan_mask. Each value is 2 bytes. */ + while (num_enabled--) { + i = find_next_bit(&scan_mask, MAX_AXIS, i); + ec_cmd_read_u16(st->ec, + EC_MEMMAP_ACC_DATA + + sizeof(s16) * + (1 + i + st->sensor_num * MAX_AXIS), + data); + *data *= st->sign[i]; + i++; + data++; + } +} + +/** + * read_ec_accel_data() - Read acceleration data from EC shared memory. + * @st: Pointer to state information for device. + * @scan_mask: Bitmap of the sensor indices to scan. + * @data: Location to store data. + * + * This is the safe function for reading the EC data. It guarantees that + * the data sampled was not modified by the EC while being read. + * + * Return: 0 if ok, -ve on error + */ +static int read_ec_accel_data(struct cros_ec_accel_legacy_state *st, + unsigned long scan_mask, s16 *data) +{ + u8 samp_id = 0xff; + u8 status = 0; + int ret; + int attempts = 0; + + /* + * Continually read all data from EC until the status byte after + * all reads reflects that the EC is not busy and the sample id + * matches the sample id from before all reads. This guarantees + * that data read in was not modified by the EC while reading. + */ + while ((status & (EC_MEMMAP_ACC_STATUS_BUSY_BIT | + EC_MEMMAP_ACC_STATUS_SAMPLE_ID_MASK)) != samp_id) { + /* If we have tried to read too many times, return error. */ + if (attempts++ >= 5) + return -EIO; + + /* Read status byte until EC is not busy. */ + ret = read_ec_until_not_busy(st); + if (ret < 0) + return ret; + status = ret; + + /* + * Store the current sample id so that we can compare to the + * sample id after reading the data. + */ + samp_id = status & EC_MEMMAP_ACC_STATUS_SAMPLE_ID_MASK; + + /* Read all EC data, format it, and store it into data. */ + read_ec_accel_data_unsafe(st, scan_mask, data); + + /* Read status byte. */ + ec_cmd_read_u8(st->ec, EC_MEMMAP_ACC_STATUS, &status); + } + + return 0; +} + +static int cros_ec_accel_legacy_read(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct cros_ec_accel_legacy_state *st = iio_priv(indio_dev); + s16 data = 0; + int ret = IIO_VAL_INT; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret = read_ec_accel_data(st, (1 << chan->scan_index), &data); + if (ret) + return ret; + *val = data; + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + *val = 0; + *val2 = ACCEL_LEGACY_NSCALE; + return IIO_VAL_INT_PLUS_NANO; + case IIO_CHAN_INFO_CALIBBIAS: + /* Calibration not supported. */ + *val = 0; + return IIO_VAL_INT; + default: + return -EINVAL; + } +} + +static int cros_ec_accel_legacy_write(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + /* + * Do nothing but don't return an error code to allow calibration + * script to work. + */ + if (mask == IIO_CHAN_INFO_CALIBBIAS) + return 0; + + return -EINVAL; +} + +static const struct iio_info cros_ec_accel_legacy_info = { + .read_raw = &cros_ec_accel_legacy_read, + .write_raw = &cros_ec_accel_legacy_write, +}; + +/** + * cros_ec_accel_legacy_capture() - The trigger handler function + * @irq: The interrupt number. + * @p: Private data - always a pointer to the poll func. + * + * On a trigger event occurring, if the pollfunc is attached then this + * handler is called as a threaded interrupt (and hence may sleep). It + * is responsible for grabbing data from the device and pushing it into + * the associated buffer. + * + * Return: IRQ_HANDLED + */ +static irqreturn_t cros_ec_accel_legacy_capture(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct cros_ec_accel_legacy_state *st = iio_priv(indio_dev); + + /* Clear capture data. */ + memset(st->capture_data, 0, sizeof(st->capture_data)); + + /* + * Read data based on which channels are enabled in scan mask. Note + * that on a capture we are always reading the calibrated data. + */ + read_ec_accel_data(st, *indio_dev->active_scan_mask, st->capture_data); + + iio_push_to_buffers_with_timestamp(indio_dev, (void *)st->capture_data, + iio_get_time_ns(indio_dev)); + + /* + * Tell the core we are done with this trigger and ready for the + * next one. + */ + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +static char *cros_ec_accel_legacy_loc_strings[] = { + [MOTIONSENSE_LOC_BASE] = "base", + [MOTIONSENSE_LOC_LID] = "lid", + [MOTIONSENSE_LOC_MAX] = "unknown", +}; + +static ssize_t cros_ec_accel_legacy_loc(struct iio_dev *indio_dev, + uintptr_t private, + const struct iio_chan_spec *chan, + char *buf) +{ + struct cros_ec_accel_legacy_state *st = iio_priv(indio_dev); + + return sprintf(buf, "%s\n", + cros_ec_accel_legacy_loc_strings[st->sensor_num + + MOTIONSENSE_LOC_BASE]); +} + +static ssize_t cros_ec_accel_legacy_id(struct iio_dev *indio_dev, + uintptr_t private, + const struct iio_chan_spec *chan, + char *buf) +{ + struct cros_ec_accel_legacy_state *st = iio_priv(indio_dev); + + return sprintf(buf, "%d\n", st->sensor_num); +} + +static const struct iio_chan_spec_ext_info cros_ec_accel_legacy_ext_info[] = { + { + .name = "id", + .shared = IIO_SHARED_BY_ALL, + .read = cros_ec_accel_legacy_id, + }, + { + .name = "location", + .shared = IIO_SHARED_BY_ALL, + .read = cros_ec_accel_legacy_loc, + }, + { } +}; + +#define CROS_EC_ACCEL_LEGACY_CHAN(_axis) \ + { \ + .type = IIO_ACCEL, \ + .channel2 = IIO_MOD_X + (_axis), \ + .modified = 1, \ + .info_mask_separate = \ + BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_CALIBBIAS), \ + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SCALE), \ + .ext_info = cros_ec_accel_legacy_ext_info, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 16, \ + .storagebits = 16, \ + }, \ + } \ + +static struct iio_chan_spec ec_accel_channels[] = { + CROS_EC_ACCEL_LEGACY_CHAN(X), + CROS_EC_ACCEL_LEGACY_CHAN(Y), + CROS_EC_ACCEL_LEGACY_CHAN(Z), + IIO_CHAN_SOFT_TIMESTAMP(MAX_AXIS) +}; + +static int cros_ec_accel_legacy_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct cros_ec_dev *ec = dev_get_drvdata(dev->parent); + struct cros_ec_sensor_platform *sensor_platform = dev_get_platdata(dev); + struct iio_dev *indio_dev; + struct cros_ec_accel_legacy_state *state; + int ret, i; + + if (!ec || !ec->ec_dev) { + dev_warn(&pdev->dev, "No EC device found.\n"); + return -EINVAL; + } + + if (!ec->ec_dev->cmd_readmem) { + dev_warn(&pdev->dev, "EC does not support direct reads.\n"); + return -EINVAL; + } + + indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*state)); + if (!indio_dev) + return -ENOMEM; + + platform_set_drvdata(pdev, indio_dev); + state = iio_priv(indio_dev); + state->ec = ec->ec_dev; + state->sensor_num = sensor_platform->sensor_num; + + indio_dev->dev.parent = dev; + indio_dev->name = pdev->name; + indio_dev->channels = ec_accel_channels; + /* + * Present the channel using HTML5 standard: + * need to invert X and Y and invert some lid axis. + */ + for (i = X ; i < MAX_AXIS; i++) { + switch (i) { + case X: + ec_accel_channels[X].scan_index = Y; + case Y: + ec_accel_channels[Y].scan_index = X; + case Z: + ec_accel_channels[Z].scan_index = Z; + } + if (state->sensor_num == MOTIONSENSE_LOC_LID && i != Y) + state->sign[i] = -1; + else + state->sign[i] = 1; + } + indio_dev->num_channels = ARRAY_SIZE(ec_accel_channels); + indio_dev->dev.parent = &pdev->dev; + indio_dev->info = &cros_ec_accel_legacy_info; + indio_dev->modes = INDIO_DIRECT_MODE; + + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, + cros_ec_accel_legacy_capture, + NULL); + if (ret) + return ret; + + return devm_iio_device_register(dev, indio_dev); +} + +static struct platform_driver cros_ec_accel_platform_driver = { + .driver = { + .name = DRV_NAME, + }, + .probe = cros_ec_accel_legacy_probe, +}; +module_platform_driver(cros_ec_accel_platform_driver); + +MODULE_DESCRIPTION("ChromeOS EC legacy accelerometer driver"); +MODULE_AUTHOR("Gwendal Grignou <gwendal@chromium.org>"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:" DRV_NAME); diff --git a/drivers/iio/accel/da280.c b/drivers/iio/accel/da280.c index ed8343aeac9c..6c214783241c 100644 --- a/drivers/iio/accel/da280.c +++ b/drivers/iio/accel/da280.c @@ -88,7 +88,6 @@ static int da280_read_raw(struct iio_dev *indio_dev, } static const struct iio_info da280_info = { - .driver_module = THIS_MODULE, .read_raw = da280_read_raw, }; diff --git a/drivers/iio/accel/da311.c b/drivers/iio/accel/da311.c index c0c1620d2a2f..aa64bca00955 100644 --- a/drivers/iio/accel/da311.c +++ b/drivers/iio/accel/da311.c @@ -212,7 +212,6 @@ static int da311_read_raw(struct iio_dev *indio_dev, } static const struct iio_info da311_info = { - .driver_module = THIS_MODULE, .read_raw = da311_read_raw, }; diff --git a/drivers/iio/accel/dmard06.c b/drivers/iio/accel/dmard06.c index 656ca8e1927f..d87e2c751475 100644 --- a/drivers/iio/accel/dmard06.c +++ b/drivers/iio/accel/dmard06.c @@ -124,7 +124,6 @@ static int dmard06_read_raw(struct iio_dev *indio_dev, } static const struct iio_info dmard06_info = { - .driver_module = THIS_MODULE, .read_raw = dmard06_read_raw, }; diff --git a/drivers/iio/accel/dmard09.c b/drivers/iio/accel/dmard09.c index d3a28f96565c..16a7e74f5e9a 100644 --- a/drivers/iio/accel/dmard09.c +++ b/drivers/iio/accel/dmard09.c @@ -93,7 +93,6 @@ static int dmard09_read_raw(struct iio_dev *indio_dev, } static const struct iio_info dmard09_info = { - .driver_module = THIS_MODULE, .read_raw = dmard09_read_raw, }; diff --git a/drivers/iio/accel/dmard10.c b/drivers/iio/accel/dmard10.c index b8736cc75656..9518ea00167e 100644 --- a/drivers/iio/accel/dmard10.c +++ b/drivers/iio/accel/dmard10.c @@ -170,7 +170,6 @@ static int dmard10_read_raw(struct iio_dev *indio_dev, } static const struct iio_info dmard10_info = { - .driver_module = THIS_MODULE, .read_raw = dmard10_read_raw, }; diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c index 2238a26aba63..c066a3bdbff7 100644 --- a/drivers/iio/accel/hid-sensor-accel-3d.c +++ b/drivers/iio/accel/hid-sensor-accel-3d.c @@ -225,7 +225,6 @@ static int accel_3d_write_raw(struct iio_dev *indio_dev, } static const struct iio_info accel_3d_info = { - .driver_module = THIS_MODULE, .read_raw = &accel_3d_read_raw, .write_raw = &accel_3d_write_raw, }; diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c index 3f968c46e667..af53a1084ee5 100644 --- a/drivers/iio/accel/kxcjk-1013.c +++ b/drivers/iio/accel/kxcjk-1013.c @@ -34,6 +34,13 @@ #define KXCJK1013_DRV_NAME "kxcjk1013" #define KXCJK1013_IRQ_NAME "kxcjk1013_event" +#define KXTF9_REG_HP_XOUT_L 0x00 +#define KXTF9_REG_HP_XOUT_H 0x01 +#define KXTF9_REG_HP_YOUT_L 0x02 +#define KXTF9_REG_HP_YOUT_H 0x03 +#define KXTF9_REG_HP_ZOUT_L 0x04 +#define KXTF9_REG_HP_ZOUT_H 0x05 + #define KXCJK1013_REG_XOUT_L 0x06 /* * From low byte X axis register, all the other addresses of Y and Z can be @@ -48,17 +55,33 @@ #define KXCJK1013_REG_DCST_RESP 0x0C #define KXCJK1013_REG_WHO_AM_I 0x0F -#define KXCJK1013_REG_INT_SRC1 0x16 +#define KXTF9_REG_TILT_POS_CUR 0x10 +#define KXTF9_REG_TILT_POS_PREV 0x11 +#define KXTF9_REG_INT_SRC1 0x15 +#define KXCJK1013_REG_INT_SRC1 0x16 /* compatible, but called INT_SRC2 in KXTF9 ds */ #define KXCJK1013_REG_INT_SRC2 0x17 #define KXCJK1013_REG_STATUS_REG 0x18 #define KXCJK1013_REG_INT_REL 0x1A #define KXCJK1013_REG_CTRL1 0x1B -#define KXCJK1013_REG_CTRL2 0x1D +#define KXTF9_REG_CTRL2 0x1C +#define KXCJK1013_REG_CTRL2 0x1D /* mostly compatible, CTRL_REG3 in KTXF9 ds */ #define KXCJK1013_REG_INT_CTRL1 0x1E #define KXCJK1013_REG_INT_CTRL2 0x1F +#define KXTF9_REG_INT_CTRL3 0x20 #define KXCJK1013_REG_DATA_CTRL 0x21 +#define KXTF9_REG_TILT_TIMER 0x28 #define KXCJK1013_REG_WAKE_TIMER 0x29 +#define KXTF9_REG_TDT_TIMER 0x2B +#define KXTF9_REG_TDT_THRESH_H 0x2C +#define KXTF9_REG_TDT_THRESH_L 0x2D +#define KXTF9_REG_TDT_TAP_TIMER 0x2E +#define KXTF9_REG_TDT_TOTAL_TIMER 0x2F +#define KXTF9_REG_TDT_LATENCY_TIMER 0x30 +#define KXTF9_REG_TDT_WINDOW_TIMER 0x31 #define KXCJK1013_REG_SELF_TEST 0x3A +#define KXTF9_REG_WAKE_THRESH 0x5A +#define KXTF9_REG_TILT_ANGLE 0x5C +#define KXTF9_REG_HYST_SET 0x5F #define KXCJK1013_REG_WAKE_THRES 0x6A #define KXCJK1013_REG_CTRL1_BIT_PC1 BIT(7) @@ -67,14 +90,33 @@ #define KXCJK1013_REG_CTRL1_BIT_GSEL1 BIT(4) #define KXCJK1013_REG_CTRL1_BIT_GSEL0 BIT(3) #define KXCJK1013_REG_CTRL1_BIT_WUFE BIT(1) -#define KXCJK1013_REG_INT_REG1_BIT_IEA BIT(4) -#define KXCJK1013_REG_INT_REG1_BIT_IEN BIT(5) + +#define KXCJK1013_REG_INT_CTRL1_BIT_IEU BIT(2) /* KXTF9 */ +#define KXCJK1013_REG_INT_CTRL1_BIT_IEL BIT(3) +#define KXCJK1013_REG_INT_CTRL1_BIT_IEA BIT(4) +#define KXCJK1013_REG_INT_CTRL1_BIT_IEN BIT(5) + +#define KXTF9_REG_TILT_BIT_LEFT_EDGE BIT(5) +#define KXTF9_REG_TILT_BIT_RIGHT_EDGE BIT(4) +#define KXTF9_REG_TILT_BIT_LOWER_EDGE BIT(3) +#define KXTF9_REG_TILT_BIT_UPPER_EDGE BIT(2) +#define KXTF9_REG_TILT_BIT_FACE_DOWN BIT(1) +#define KXTF9_REG_TILT_BIT_FACE_UP BIT(0) #define KXCJK1013_DATA_MASK_12_BIT 0x0FFF #define KXCJK1013_MAX_STARTUP_TIME_US 100000 #define KXCJK1013_SLEEP_DELAY_MS 2000 +#define KXCJK1013_REG_INT_SRC1_BIT_TPS BIT(0) /* KXTF9 */ +#define KXCJK1013_REG_INT_SRC1_BIT_WUFS BIT(1) +#define KXCJK1013_REG_INT_SRC1_MASK_TDTS (BIT(2) | BIT(3)) /* KXTF9 */ +#define KXCJK1013_REG_INT_SRC1_TAP_NONE 0 +#define KXCJK1013_REG_INT_SRC1_TAP_SINGLE BIT(2) +#define KXCJK1013_REG_INT_SRC1_TAP_DOUBLE BIT(3) +#define KXCJK1013_REG_INT_SRC1_BIT_DRDY BIT(4) + +/* KXCJK: INT_SOURCE2: motion detect, KXTF9: INT_SRC_REG1: tap detect */ #define KXCJK1013_REG_INT_SRC2_BIT_ZP BIT(0) #define KXCJK1013_REG_INT_SRC2_BIT_ZN BIT(1) #define KXCJK1013_REG_INT_SRC2_BIT_YP BIT(2) @@ -88,6 +130,7 @@ enum kx_chipset { KXCJK1013, KXCJ91008, KXTJ21009, + KXTF9, KX_MAX_CHIPS /* this must be last */ }; @@ -128,15 +171,42 @@ enum kxcjk1013_range { KXCJK1013_RANGE_8G, }; -static const struct { +struct kx_odr_map { int val; int val2; int odr_bits; -} samp_freq_table[] = { {0, 781000, 0x08}, {1, 563000, 0x09}, - {3, 125000, 0x0A}, {6, 250000, 0x0B}, {12, 500000, 0}, - {25, 0, 0x01}, {50, 0, 0x02}, {100, 0, 0x03}, - {200, 0, 0x04}, {400, 0, 0x05}, {800, 0, 0x06}, - {1600, 0, 0x07} }; + int wuf_bits; +}; + +static const struct kx_odr_map samp_freq_table[] = { + { 0, 781000, 0x08, 0x00 }, + { 1, 563000, 0x09, 0x01 }, + { 3, 125000, 0x0A, 0x02 }, + { 6, 250000, 0x0B, 0x03 }, + { 12, 500000, 0x00, 0x04 }, + { 25, 0, 0x01, 0x05 }, + { 50, 0, 0x02, 0x06 }, + { 100, 0, 0x03, 0x06 }, + { 200, 0, 0x04, 0x06 }, + { 400, 0, 0x05, 0x06 }, + { 800, 0, 0x06, 0x06 }, + { 1600, 0, 0x07, 0x06 }, +}; + +static const char *const kxcjk1013_samp_freq_avail = + "0.781000 1.563000 3.125000 6.250000 12.500000 25 50 100 200 400 800 1600"; + +static const struct kx_odr_map kxtf9_samp_freq_table[] = { + { 25, 0, 0x01, 0x00 }, + { 50, 0, 0x02, 0x01 }, + { 100, 0, 0x03, 0x01 }, + { 200, 0, 0x04, 0x01 }, + { 400, 0, 0x05, 0x01 }, + { 800, 0, 0x06, 0x01 }, +}; + +static const char *const kxtf9_samp_freq_avail = + "25 50 100 200 400 800"; /* Refer to section 4 of the specification */ static const struct { @@ -188,6 +258,15 @@ static const struct { {0x06, 3000}, {0x07, 2000}, }, + /* KXTF9 */ + { + {0x01, 81000}, + {0x02, 41000}, + {0x03, 21000}, + {0x04, 11000}, + {0x05, 5100}, + {0x06, 2700}, + }, }; static const struct { @@ -198,23 +277,6 @@ static const struct { {19163, 1, 0}, {38326, 0, 1} }; -static const struct { - int val; - int val2; - int odr_bits; -} wake_odr_data_rate_table[] = { {0, 781000, 0x00}, - {1, 563000, 0x01}, - {3, 125000, 0x02}, - {6, 250000, 0x03}, - {12, 500000, 0x04}, - {25, 0, 0x05}, - {50, 0, 0x06}, - {100, 0, 0x06}, - {200, 0, 0x06}, - {400, 0, 0x06}, - {800, 0, 0x06}, - {1600, 0, 0x06} }; - static int kxcjk1013_set_mode(struct kxcjk1013_data *data, enum kxcjk1013_mode mode) { @@ -341,9 +403,9 @@ static int kxcjk1013_chip_init(struct kxcjk1013_data *data) } if (data->active_high_intr) - ret |= KXCJK1013_REG_INT_REG1_BIT_IEA; + ret |= KXCJK1013_REG_INT_CTRL1_BIT_IEA; else - ret &= ~KXCJK1013_REG_INT_REG1_BIT_IEA; + ret &= ~KXCJK1013_REG_INT_CTRL1_BIT_IEA; ret = i2c_smbus_write_byte_data(data->client, KXCJK1013_REG_INT_CTRL1, ret); @@ -401,7 +463,7 @@ static int kxcjk1013_set_power_state(struct kxcjk1013_data *data, bool on) static int kxcjk1013_chip_update_thresholds(struct kxcjk1013_data *data) { - int ret; + int waketh_reg, ret; ret = i2c_smbus_write_byte_data(data->client, KXCJK1013_REG_WAKE_TIMER, @@ -412,8 +474,9 @@ static int kxcjk1013_chip_update_thresholds(struct kxcjk1013_data *data) return ret; } - ret = i2c_smbus_write_byte_data(data->client, - KXCJK1013_REG_WAKE_THRES, + waketh_reg = data->chipset == KXTF9 ? + KXTF9_REG_WAKE_THRESH : KXCJK1013_REG_WAKE_THRES; + ret = i2c_smbus_write_byte_data(data->client, waketh_reg, data->wake_thres); if (ret < 0) { dev_err(&data->client->dev, "Error writing reg_wake_thres\n"); @@ -449,9 +512,9 @@ static int kxcjk1013_setup_any_motion_interrupt(struct kxcjk1013_data *data, } if (status) - ret |= KXCJK1013_REG_INT_REG1_BIT_IEN; + ret |= KXCJK1013_REG_INT_CTRL1_BIT_IEN; else - ret &= ~KXCJK1013_REG_INT_REG1_BIT_IEN; + ret &= ~KXCJK1013_REG_INT_CTRL1_BIT_IEN; ret = i2c_smbus_write_byte_data(data->client, KXCJK1013_REG_INT_CTRL1, ret); @@ -509,9 +572,9 @@ static int kxcjk1013_setup_new_data_interrupt(struct kxcjk1013_data *data, } if (status) - ret |= KXCJK1013_REG_INT_REG1_BIT_IEN; + ret |= KXCJK1013_REG_INT_CTRL1_BIT_IEN; else - ret &= ~KXCJK1013_REG_INT_REG1_BIT_IEN; + ret &= ~KXCJK1013_REG_INT_CTRL1_BIT_IEN; ret = i2c_smbus_write_byte_data(data->client, KXCJK1013_REG_INT_CTRL1, ret); @@ -547,28 +610,30 @@ static int kxcjk1013_setup_new_data_interrupt(struct kxcjk1013_data *data, return 0; } -static int kxcjk1013_convert_freq_to_bit(int val, int val2) +static const struct kx_odr_map *kxcjk1013_find_odr_value( + const struct kx_odr_map *map, size_t map_size, int val, int val2) { int i; - for (i = 0; i < ARRAY_SIZE(samp_freq_table); ++i) { - if (samp_freq_table[i].val == val && - samp_freq_table[i].val2 == val2) { - return samp_freq_table[i].odr_bits; - } + for (i = 0; i < map_size; ++i) { + if (map[i].val == val && map[i].val2 == val2) + return &map[i]; } - return -EINVAL; + return ERR_PTR(-EINVAL); } -static int kxcjk1013_convert_wake_odr_to_bit(int val, int val2) +static int kxcjk1013_convert_odr_value(const struct kx_odr_map *map, + size_t map_size, int odr_bits, + int *val, int *val2) { int i; - for (i = 0; i < ARRAY_SIZE(wake_odr_data_rate_table); ++i) { - if (wake_odr_data_rate_table[i].val == val && - wake_odr_data_rate_table[i].val2 == val2) { - return wake_odr_data_rate_table[i].odr_bits; + for (i = 0; i < map_size; ++i) { + if (map[i].odr_bits == odr_bits) { + *val = map[i].val; + *val2 = map[i].val2; + return IIO_VAL_INT_PLUS_MICRO; } } @@ -578,16 +643,24 @@ static int kxcjk1013_convert_wake_odr_to_bit(int val, int val2) static int kxcjk1013_set_odr(struct kxcjk1013_data *data, int val, int val2) { int ret; - int odr_bits; enum kxcjk1013_mode store_mode; + const struct kx_odr_map *odr_setting; ret = kxcjk1013_get_mode(data, &store_mode); if (ret < 0) return ret; - odr_bits = kxcjk1013_convert_freq_to_bit(val, val2); - if (odr_bits < 0) - return odr_bits; + if (data->chipset == KXTF9) + odr_setting = kxcjk1013_find_odr_value(kxtf9_samp_freq_table, + ARRAY_SIZE(kxtf9_samp_freq_table), + val, val2); + else + odr_setting = kxcjk1013_find_odr_value(samp_freq_table, + ARRAY_SIZE(samp_freq_table), + val, val2); + + if (IS_ERR(odr_setting)) + return PTR_ERR(odr_setting); /* To change ODR, the chip must be set to STANDBY as per spec */ ret = kxcjk1013_set_mode(data, STANDBY); @@ -595,20 +668,16 @@ static int kxcjk1013_set_odr(struct kxcjk1013_data *data, int val, int val2) return ret; ret = i2c_smbus_write_byte_data(data->client, KXCJK1013_REG_DATA_CTRL, - odr_bits); + odr_setting->odr_bits); if (ret < 0) { dev_err(&data->client->dev, "Error writing data_ctrl\n"); return ret; } - data->odr_bits = odr_bits; - - odr_bits = kxcjk1013_convert_wake_odr_to_bit(val, val2); - if (odr_bits < 0) - return odr_bits; + data->odr_bits = odr_setting->odr_bits; ret = i2c_smbus_write_byte_data(data->client, KXCJK1013_REG_CTRL2, - odr_bits); + odr_setting->wuf_bits); if (ret < 0) { dev_err(&data->client->dev, "Error writing reg_ctrl2\n"); return ret; @@ -625,17 +694,14 @@ static int kxcjk1013_set_odr(struct kxcjk1013_data *data, int val, int val2) static int kxcjk1013_get_odr(struct kxcjk1013_data *data, int *val, int *val2) { - int i; - - for (i = 0; i < ARRAY_SIZE(samp_freq_table); ++i) { - if (samp_freq_table[i].odr_bits == data->odr_bits) { - *val = samp_freq_table[i].val; - *val2 = samp_freq_table[i].val2; - return IIO_VAL_INT_PLUS_MICRO; - } - } - - return -EINVAL; + if (data->chipset == KXTF9) + return kxcjk1013_convert_odr_value(kxtf9_samp_freq_table, + ARRAY_SIZE(kxtf9_samp_freq_table), + data->odr_bits, val, val2); + else + return kxcjk1013_convert_odr_value(samp_freq_table, + ARRAY_SIZE(samp_freq_table), + data->odr_bits, val, val2); } static int kxcjk1013_get_acc_reg(struct kxcjk1013_data *data, int axis) @@ -886,13 +952,29 @@ static int kxcjk1013_buffer_postdisable(struct iio_dev *indio_dev) return kxcjk1013_set_power_state(data, false); } -static IIO_CONST_ATTR_SAMP_FREQ_AVAIL( - "0.781000 1.563000 3.125000 6.250000 12.500000 25 50 100 200 400 800 1600"); +static ssize_t kxcjk1013_get_samp_freq_avail(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct kxcjk1013_data *data = iio_priv(indio_dev); + const char *str; + + if (data->chipset == KXTF9) + str = kxtf9_samp_freq_avail; + else + str = kxcjk1013_samp_freq_avail; + + return sprintf(buf, "%s\n", str); +} + +static IIO_DEVICE_ATTR(in_accel_sampling_frequency_available, S_IRUGO, + kxcjk1013_get_samp_freq_avail, NULL, 0); static IIO_CONST_ATTR(in_accel_scale_available, "0.009582 0.019163 0.038326"); static struct attribute *kxcjk1013_attributes[] = { - &iio_const_attr_sampling_frequency_available.dev_attr.attr, + &iio_dev_attr_in_accel_sampling_frequency_available.dev_attr.attr, &iio_const_attr_in_accel_scale_available.dev_attr.attr, NULL, }; @@ -950,7 +1032,6 @@ static const struct iio_info kxcjk1013_info = { .write_event_value = kxcjk1013_write_event, .write_event_config = kxcjk1013_write_event_config, .read_event_config = kxcjk1013_read_event_config, - .driver_module = THIS_MODULE, }; static const unsigned long kxcjk1013_scan_masks[] = {0x7, 0}; @@ -1036,9 +1117,74 @@ static int kxcjk1013_data_rdy_trigger_set_state(struct iio_trigger *trig, static const struct iio_trigger_ops kxcjk1013_trigger_ops = { .set_trigger_state = kxcjk1013_data_rdy_trigger_set_state, .try_reenable = kxcjk1013_trig_try_reen, - .owner = THIS_MODULE, }; +static void kxcjk1013_report_motion_event(struct iio_dev *indio_dev) +{ + struct kxcjk1013_data *data = iio_priv(indio_dev); + + int ret = i2c_smbus_read_byte_data(data->client, + KXCJK1013_REG_INT_SRC2); + if (ret < 0) { + dev_err(&data->client->dev, "Error reading reg_int_src2\n"); + return; + } + + if (ret & KXCJK1013_REG_INT_SRC2_BIT_XN) + iio_push_event(indio_dev, + IIO_MOD_EVENT_CODE(IIO_ACCEL, + 0, + IIO_MOD_X, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_FALLING), + data->timestamp); + + if (ret & KXCJK1013_REG_INT_SRC2_BIT_XP) + iio_push_event(indio_dev, + IIO_MOD_EVENT_CODE(IIO_ACCEL, + 0, + IIO_MOD_X, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_RISING), + data->timestamp); + + if (ret & KXCJK1013_REG_INT_SRC2_BIT_YN) + iio_push_event(indio_dev, + IIO_MOD_EVENT_CODE(IIO_ACCEL, + 0, + IIO_MOD_Y, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_FALLING), + data->timestamp); + + if (ret & KXCJK1013_REG_INT_SRC2_BIT_YP) + iio_push_event(indio_dev, + IIO_MOD_EVENT_CODE(IIO_ACCEL, + 0, + IIO_MOD_Y, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_RISING), + data->timestamp); + + if (ret & KXCJK1013_REG_INT_SRC2_BIT_ZN) + iio_push_event(indio_dev, + IIO_MOD_EVENT_CODE(IIO_ACCEL, + 0, + IIO_MOD_Z, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_FALLING), + data->timestamp); + + if (ret & KXCJK1013_REG_INT_SRC2_BIT_ZP) + iio_push_event(indio_dev, + IIO_MOD_EVENT_CODE(IIO_ACCEL, + 0, + IIO_MOD_Z, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_RISING), + data->timestamp); +} + static irqreturn_t kxcjk1013_event_handler(int irq, void *private) { struct iio_dev *indio_dev = private; @@ -1051,66 +1197,17 @@ static irqreturn_t kxcjk1013_event_handler(int irq, void *private) goto ack_intr; } - if (ret & 0x02) { - ret = i2c_smbus_read_byte_data(data->client, - KXCJK1013_REG_INT_SRC2); - if (ret < 0) { - dev_err(&data->client->dev, - "Error reading reg_int_src2\n"); - goto ack_intr; - } - - if (ret & KXCJK1013_REG_INT_SRC2_BIT_XN) - iio_push_event(indio_dev, - IIO_MOD_EVENT_CODE(IIO_ACCEL, - 0, - IIO_MOD_X, - IIO_EV_TYPE_THRESH, - IIO_EV_DIR_FALLING), - data->timestamp); - if (ret & KXCJK1013_REG_INT_SRC2_BIT_XP) - iio_push_event(indio_dev, - IIO_MOD_EVENT_CODE(IIO_ACCEL, - 0, - IIO_MOD_X, - IIO_EV_TYPE_THRESH, - IIO_EV_DIR_RISING), - data->timestamp); - - - if (ret & KXCJK1013_REG_INT_SRC2_BIT_YN) - iio_push_event(indio_dev, - IIO_MOD_EVENT_CODE(IIO_ACCEL, - 0, - IIO_MOD_Y, - IIO_EV_TYPE_THRESH, - IIO_EV_DIR_FALLING), - data->timestamp); - if (ret & KXCJK1013_REG_INT_SRC2_BIT_YP) - iio_push_event(indio_dev, - IIO_MOD_EVENT_CODE(IIO_ACCEL, - 0, - IIO_MOD_Y, - IIO_EV_TYPE_THRESH, - IIO_EV_DIR_RISING), - data->timestamp); - - if (ret & KXCJK1013_REG_INT_SRC2_BIT_ZN) - iio_push_event(indio_dev, - IIO_MOD_EVENT_CODE(IIO_ACCEL, - 0, - IIO_MOD_Z, - IIO_EV_TYPE_THRESH, - IIO_EV_DIR_FALLING), - data->timestamp); - if (ret & KXCJK1013_REG_INT_SRC2_BIT_ZP) + if (ret & KXCJK1013_REG_INT_SRC1_BIT_WUFS) { + if (data->chipset == KXTF9) iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, - IIO_MOD_Z, + IIO_MOD_X_AND_Y_AND_Z, IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), data->timestamp); + else + kxcjk1013_report_motion_event(indio_dev); } ack_intr: @@ -1403,6 +1500,7 @@ static const struct i2c_device_id kxcjk1013_id[] = { {"kxcjk1013", KXCJK1013}, {"kxcj91008", KXCJ91008}, {"kxtj21009", KXTJ21009}, + {"kxtf9", KXTF9}, {"SMO8500", KXCJ91008}, {} }; diff --git a/drivers/iio/accel/kxsd9.c b/drivers/iio/accel/kxsd9.c index 9af60ac70738..0c0df4fce420 100644 --- a/drivers/iio/accel/kxsd9.c +++ b/drivers/iio/accel/kxsd9.c @@ -390,7 +390,6 @@ static const struct iio_info kxsd9_info = { .read_raw = &kxsd9_read_raw, .write_raw = &kxsd9_write_raw, .attrs = &kxsd9_attribute_group, - .driver_module = THIS_MODULE, }; /* Four channels apart from timestamp, scan mask = 0x0f */ diff --git a/drivers/iio/accel/mc3230.c b/drivers/iio/accel/mc3230.c index 4ea2ff623a6d..8b11604eed63 100644 --- a/drivers/iio/accel/mc3230.c +++ b/drivers/iio/accel/mc3230.c @@ -107,7 +107,6 @@ static int mc3230_read_raw(struct iio_dev *indio_dev, } static const struct iio_info mc3230_info = { - .driver_module = THIS_MODULE, .read_raw = mc3230_read_raw, }; diff --git a/drivers/iio/accel/mma7455_core.c b/drivers/iio/accel/mma7455_core.c index 6551085bedd7..da0ceaac46b5 100644 --- a/drivers/iio/accel/mma7455_core.c +++ b/drivers/iio/accel/mma7455_core.c @@ -199,7 +199,6 @@ static const struct iio_info mma7455_info = { .attrs = &mma7455_group, .read_raw = mma7455_read_raw, .write_raw = mma7455_write_raw, - .driver_module = THIS_MODULE, }; #define MMA7455_CHANNEL(axis, idx) { \ diff --git a/drivers/iio/accel/mma7660.c b/drivers/iio/accel/mma7660.c index 42fa57e41bdd..f1a13724efb3 100644 --- a/drivers/iio/accel/mma7660.c +++ b/drivers/iio/accel/mma7660.c @@ -168,7 +168,6 @@ static int mma7660_read_raw(struct iio_dev *indio_dev, } static const struct iio_info mma7660_info = { - .driver_module = THIS_MODULE, .read_raw = mma7660_read_raw, .attrs = &mma7660_attribute_group, }; diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c index eb6e3dc789b2..bfd4bc806fc2 100644 --- a/drivers/iio/accel/mma8452.c +++ b/drivers/iio/accel/mma8452.c @@ -59,7 +59,9 @@ #define MMA8452_FF_MT_THS 0x17 #define MMA8452_FF_MT_THS_MASK 0x7f #define MMA8452_FF_MT_COUNT 0x18 +#define MMA8452_FF_MT_CHAN_SHIFT 3 #define MMA8452_TRANSIENT_CFG 0x1d +#define MMA8452_TRANSIENT_CFG_CHAN(chan) BIT(chan + 1) #define MMA8452_TRANSIENT_CFG_HPF_BYP BIT(0) #define MMA8452_TRANSIENT_CFG_ELE BIT(4) #define MMA8452_TRANSIENT_SRC 0x1e @@ -69,6 +71,7 @@ #define MMA8452_TRANSIENT_THS 0x1f #define MMA8452_TRANSIENT_THS_MASK GENMASK(6, 0) #define MMA8452_TRANSIENT_COUNT 0x20 +#define MMA8452_TRANSIENT_CHAN_SHIFT 1 #define MMA8452_CTRL_REG1 0x2a #define MMA8452_CTRL_ACTIVE BIT(0) #define MMA8452_CTRL_DR_MASK GENMASK(5, 3) @@ -107,6 +110,51 @@ struct mma8452_data { const struct mma_chip_info *chip_info; }; + /** + * struct mma8452_event_regs - chip specific data related to events + * @ev_cfg: event config register address + * @ev_cfg_ele: latch bit in event config register + * @ev_cfg_chan_shift: number of the bit to enable events in X + * direction; in event config register + * @ev_src: event source register address + * @ev_ths: event threshold register address + * @ev_ths_mask: mask for the threshold value + * @ev_count: event count (period) register address + * + * Since not all chips supported by the driver support comparing high pass + * filtered data for events (interrupts), different interrupt sources are + * used for different chips and the relevant registers are included here. + */ +struct mma8452_event_regs { + u8 ev_cfg; + u8 ev_cfg_ele; + u8 ev_cfg_chan_shift; + u8 ev_src; + u8 ev_ths; + u8 ev_ths_mask; + u8 ev_count; +}; + +static const struct mma8452_event_regs ev_regs_accel_falling = { + .ev_cfg = MMA8452_FF_MT_CFG, + .ev_cfg_ele = MMA8452_FF_MT_CFG_ELE, + .ev_cfg_chan_shift = MMA8452_FF_MT_CHAN_SHIFT, + .ev_src = MMA8452_FF_MT_SRC, + .ev_ths = MMA8452_FF_MT_THS, + .ev_ths_mask = MMA8452_FF_MT_THS_MASK, + .ev_count = MMA8452_FF_MT_COUNT +}; + +static const struct mma8452_event_regs ev_regs_accel_rising = { + .ev_cfg = MMA8452_TRANSIENT_CFG, + .ev_cfg_ele = MMA8452_TRANSIENT_CFG_ELE, + .ev_cfg_chan_shift = MMA8452_TRANSIENT_CHAN_SHIFT, + .ev_src = MMA8452_TRANSIENT_SRC, + .ev_ths = MMA8452_TRANSIENT_THS, + .ev_ths_mask = MMA8452_TRANSIENT_THS_MASK, + .ev_count = MMA8452_TRANSIENT_COUNT, +}; + /** * struct mma_chip_info - chip specific data * @chip_id: WHO_AM_I register's value @@ -116,40 +164,16 @@ struct mma8452_data { * @mma_scales: scale factors for converting register values * to m/s^2; 3 modes: 2g, 4g, 8g; 2 integers * per mode: m/s^2 and micro m/s^2 - * @ev_cfg: event config register address - * @ev_cfg_ele: latch bit in event config register - * @ev_cfg_chan_shift: number of the bit to enable events in X - * direction; in event config register - * @ev_src: event source register address - * @ev_src_xe: bit in event source register that indicates - * an event in X direction - * @ev_src_ye: bit in event source register that indicates - * an event in Y direction - * @ev_src_ze: bit in event source register that indicates - * an event in Z direction - * @ev_ths: event threshold register address - * @ev_ths_mask: mask for the threshold value - * @ev_count: event count (period) register address - * - * Since not all chips supported by the driver support comparing high pass - * filtered data for events (interrupts), different interrupt sources are - * used for different chips and the relevant registers are included here. + * @all_events: all events supported by this chip + * @enabled_events: event flags enabled and handled by this driver */ struct mma_chip_info { u8 chip_id; const struct iio_chan_spec *channels; int num_channels; const int mma_scales[3][2]; - u8 ev_cfg; - u8 ev_cfg_ele; - u8 ev_cfg_chan_shift; - u8 ev_src; - u8 ev_src_xe; - u8 ev_src_ye; - u8 ev_src_ze; - u8 ev_ths; - u8 ev_ths_mask; - u8 ev_count; + int all_events; + int enabled_events; }; enum { @@ -394,11 +418,11 @@ static ssize_t mma8452_show_os_ratio_avail(struct device *dev, } static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(mma8452_show_samp_freq_avail); -static IIO_DEVICE_ATTR(in_accel_scale_available, S_IRUGO, +static IIO_DEVICE_ATTR(in_accel_scale_available, 0444, mma8452_show_scale_avail, NULL, 0); static IIO_DEVICE_ATTR(in_accel_filter_high_pass_3db_frequency_available, - S_IRUGO, mma8452_show_hp_cutoff_avail, NULL, 0); -static IIO_DEVICE_ATTR(in_accel_oversampling_ratio_available, S_IRUGO, + 0444, mma8452_show_hp_cutoff_avail, NULL, 0); +static IIO_DEVICE_ATTR(in_accel_oversampling_ratio_available, 0444, mma8452_show_os_ratio_avail, NULL, 0); static int mma8452_get_samp_freq_index(struct mma8452_data *data, @@ -602,9 +626,8 @@ static int mma8452_set_power_mode(struct mma8452_data *data, u8 mode) static int mma8452_freefall_mode_enabled(struct mma8452_data *data) { int val; - const struct mma_chip_info *chip = data->chip_info; - val = i2c_smbus_read_byte_data(data->client, chip->ev_cfg); + val = i2c_smbus_read_byte_data(data->client, MMA8452_FF_MT_CFG); if (val < 0) return val; @@ -614,29 +637,28 @@ static int mma8452_freefall_mode_enabled(struct mma8452_data *data) static int mma8452_set_freefall_mode(struct mma8452_data *data, bool state) { int val; - const struct mma_chip_info *chip = data->chip_info; if ((state && mma8452_freefall_mode_enabled(data)) || (!state && !(mma8452_freefall_mode_enabled(data)))) return 0; - val = i2c_smbus_read_byte_data(data->client, chip->ev_cfg); + val = i2c_smbus_read_byte_data(data->client, MMA8452_FF_MT_CFG); if (val < 0) return val; if (state) { - val |= BIT(idx_x + chip->ev_cfg_chan_shift); - val |= BIT(idx_y + chip->ev_cfg_chan_shift); - val |= BIT(idx_z + chip->ev_cfg_chan_shift); + val |= BIT(idx_x + MMA8452_FF_MT_CHAN_SHIFT); + val |= BIT(idx_y + MMA8452_FF_MT_CHAN_SHIFT); + val |= BIT(idx_z + MMA8452_FF_MT_CHAN_SHIFT); val &= ~MMA8452_FF_MT_CFG_OAE; } else { - val &= ~BIT(idx_x + chip->ev_cfg_chan_shift); - val &= ~BIT(idx_y + chip->ev_cfg_chan_shift); - val &= ~BIT(idx_z + chip->ev_cfg_chan_shift); + val &= ~BIT(idx_x + MMA8452_FF_MT_CHAN_SHIFT); + val &= ~BIT(idx_y + MMA8452_FF_MT_CHAN_SHIFT); + val &= ~BIT(idx_z + MMA8452_FF_MT_CHAN_SHIFT); val |= MMA8452_FF_MT_CFG_OAE; } - return mma8452_change_config(data, chip->ev_cfg, val); + return mma8452_change_config(data, MMA8452_FF_MT_CFG, val); } static int mma8452_set_hp_filter_frequency(struct mma8452_data *data, @@ -740,7 +762,37 @@ static int mma8452_write_raw(struct iio_dev *indio_dev, return ret; } -static int mma8452_read_thresh(struct iio_dev *indio_dev, +static int mma8452_get_event_regs(struct mma8452_data *data, + const struct iio_chan_spec *chan, enum iio_event_direction dir, + const struct mma8452_event_regs **ev_reg) +{ + if (!chan) + return -EINVAL; + + switch (chan->type) { + case IIO_ACCEL: + switch (dir) { + case IIO_EV_DIR_RISING: + if ((data->chip_info->all_events + & MMA8452_INT_TRANS) && + (data->chip_info->enabled_events + & MMA8452_INT_TRANS)) + *ev_reg = &ev_regs_accel_rising; + else + *ev_reg = &ev_regs_accel_falling; + return 0; + case IIO_EV_DIR_FALLING: + *ev_reg = &ev_regs_accel_falling; + return 0; + default: + return -EINVAL; + } + default: + return -EINVAL; + } +} + +static int mma8452_read_event_value(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, @@ -749,21 +801,24 @@ static int mma8452_read_thresh(struct iio_dev *indio_dev, { struct mma8452_data *data = iio_priv(indio_dev); int ret, us, power_mode; + const struct mma8452_event_regs *ev_regs; + + ret = mma8452_get_event_regs(data, chan, dir, &ev_regs); + if (ret) + return ret; switch (info) { case IIO_EV_INFO_VALUE: - ret = i2c_smbus_read_byte_data(data->client, - data->chip_info->ev_ths); + ret = i2c_smbus_read_byte_data(data->client, ev_regs->ev_ths); if (ret < 0) return ret; - *val = ret & data->chip_info->ev_ths_mask; + *val = ret & ev_regs->ev_ths_mask; return IIO_VAL_INT; case IIO_EV_INFO_PERIOD: - ret = i2c_smbus_read_byte_data(data->client, - data->chip_info->ev_count); + ret = i2c_smbus_read_byte_data(data->client, ev_regs->ev_count); if (ret < 0) return ret; @@ -800,7 +855,7 @@ static int mma8452_read_thresh(struct iio_dev *indio_dev, } } -static int mma8452_write_thresh(struct iio_dev *indio_dev, +static int mma8452_write_event_value(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, @@ -809,14 +864,18 @@ static int mma8452_write_thresh(struct iio_dev *indio_dev, { struct mma8452_data *data = iio_priv(indio_dev); int ret, reg, steps; + const struct mma8452_event_regs *ev_regs; + + ret = mma8452_get_event_regs(data, chan, dir, &ev_regs); + if (ret) + return ret; switch (info) { case IIO_EV_INFO_VALUE: - if (val < 0 || val > MMA8452_TRANSIENT_THS_MASK) + if (val < 0 || val > ev_regs->ev_ths_mask) return -EINVAL; - return mma8452_change_config(data, data->chip_info->ev_ths, - val); + return mma8452_change_config(data, ev_regs->ev_ths, val); case IIO_EV_INFO_PERIOD: ret = mma8452_get_power_mode(data); @@ -830,8 +889,7 @@ static int mma8452_write_thresh(struct iio_dev *indio_dev, if (steps < 0 || steps > 0xff) return -EINVAL; - return mma8452_change_config(data, data->chip_info->ev_count, - steps); + return mma8452_change_config(data, ev_regs->ev_count, steps); case IIO_EV_INFO_HIGH_PASS_FILTER_3DB: reg = i2c_smbus_read_byte_data(data->client, @@ -861,23 +919,24 @@ static int mma8452_read_event_config(struct iio_dev *indio_dev, enum iio_event_direction dir) { struct mma8452_data *data = iio_priv(indio_dev); - const struct mma_chip_info *chip = data->chip_info; int ret; + const struct mma8452_event_regs *ev_regs; + + ret = mma8452_get_event_regs(data, chan, dir, &ev_regs); + if (ret) + return ret; switch (dir) { case IIO_EV_DIR_FALLING: return mma8452_freefall_mode_enabled(data); case IIO_EV_DIR_RISING: - if (mma8452_freefall_mode_enabled(data)) - return 0; - ret = i2c_smbus_read_byte_data(data->client, - data->chip_info->ev_cfg); + ev_regs->ev_cfg); if (ret < 0) return ret; return !!(ret & BIT(chan->scan_index + - chip->ev_cfg_chan_shift)); + ev_regs->ev_cfg_chan_shift)); default: return -EINVAL; } @@ -890,8 +949,12 @@ static int mma8452_write_event_config(struct iio_dev *indio_dev, int state) { struct mma8452_data *data = iio_priv(indio_dev); - const struct mma_chip_info *chip = data->chip_info; int val, ret; + const struct mma8452_event_regs *ev_regs; + + ret = mma8452_get_event_regs(data, chan, dir, &ev_regs); + if (ret) + return ret; ret = mma8452_set_runtime_pm_state(data->client, state); if (ret) @@ -901,28 +964,30 @@ static int mma8452_write_event_config(struct iio_dev *indio_dev, case IIO_EV_DIR_FALLING: return mma8452_set_freefall_mode(data, state); case IIO_EV_DIR_RISING: - val = i2c_smbus_read_byte_data(data->client, chip->ev_cfg); + val = i2c_smbus_read_byte_data(data->client, ev_regs->ev_cfg); if (val < 0) return val; if (state) { if (mma8452_freefall_mode_enabled(data)) { - val &= ~BIT(idx_x + chip->ev_cfg_chan_shift); - val &= ~BIT(idx_y + chip->ev_cfg_chan_shift); - val &= ~BIT(idx_z + chip->ev_cfg_chan_shift); + val &= ~BIT(idx_x + ev_regs->ev_cfg_chan_shift); + val &= ~BIT(idx_y + ev_regs->ev_cfg_chan_shift); + val &= ~BIT(idx_z + ev_regs->ev_cfg_chan_shift); val |= MMA8452_FF_MT_CFG_OAE; } - val |= BIT(chan->scan_index + chip->ev_cfg_chan_shift); + val |= BIT(chan->scan_index + + ev_regs->ev_cfg_chan_shift); } else { if (mma8452_freefall_mode_enabled(data)) return 0; - val &= ~BIT(chan->scan_index + chip->ev_cfg_chan_shift); + val &= ~BIT(chan->scan_index + + ev_regs->ev_cfg_chan_shift); } - val |= chip->ev_cfg_ele; + val |= ev_regs->ev_cfg_ele; - return mma8452_change_config(data, chip->ev_cfg, val); + return mma8452_change_config(data, ev_regs->ev_cfg, val); default: return -EINVAL; } @@ -934,35 +999,25 @@ static void mma8452_transient_interrupt(struct iio_dev *indio_dev) s64 ts = iio_get_time_ns(indio_dev); int src; - src = i2c_smbus_read_byte_data(data->client, data->chip_info->ev_src); + src = i2c_smbus_read_byte_data(data->client, MMA8452_TRANSIENT_SRC); if (src < 0) return; - if (mma8452_freefall_mode_enabled(data)) { - iio_push_event(indio_dev, - IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, - IIO_MOD_X_AND_Y_AND_Z, - IIO_EV_TYPE_MAG, - IIO_EV_DIR_FALLING), - ts); - return; - } - - if (src & data->chip_info->ev_src_xe) + if (src & MMA8452_TRANSIENT_SRC_XTRANSE) iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, IIO_MOD_X, IIO_EV_TYPE_MAG, IIO_EV_DIR_RISING), ts); - if (src & data->chip_info->ev_src_ye) + if (src & MMA8452_TRANSIENT_SRC_YTRANSE) iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, IIO_MOD_Y, IIO_EV_TYPE_MAG, IIO_EV_DIR_RISING), ts); - if (src & data->chip_info->ev_src_ze) + if (src & MMA8452_TRANSIENT_SRC_ZTRANSE) iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, IIO_MOD_Z, IIO_EV_TYPE_MAG, @@ -974,7 +1029,6 @@ static irqreturn_t mma8452_interrupt(int irq, void *p) { struct iio_dev *indio_dev = p; struct mma8452_data *data = iio_priv(indio_dev); - const struct mma_chip_info *chip = data->chip_info; int ret = IRQ_NONE; int src; @@ -982,15 +1036,29 @@ static irqreturn_t mma8452_interrupt(int irq, void *p) if (src < 0) return IRQ_NONE; + if (!(src & data->chip_info->enabled_events)) + return IRQ_NONE; + if (src & MMA8452_INT_DRDY) { iio_trigger_poll_chained(indio_dev->trig); ret = IRQ_HANDLED; } - if ((src & MMA8452_INT_TRANS && - chip->ev_src == MMA8452_TRANSIENT_SRC) || - (src & MMA8452_INT_FF_MT && - chip->ev_src == MMA8452_FF_MT_SRC)) { + if (src & MMA8452_INT_FF_MT) { + if (mma8452_freefall_mode_enabled(data)) { + s64 ts = iio_get_time_ns(indio_dev); + + iio_push_event(indio_dev, + IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, + IIO_MOD_X_AND_Y_AND_Z, + IIO_EV_TYPE_MAG, + IIO_EV_DIR_FALLING), + ts); + } + ret = IRQ_HANDLED; + } + + if (src & MMA8452_INT_TRANS) { mma8452_transient_interrupt(indio_dev); ret = IRQ_HANDLED; } @@ -1020,8 +1088,8 @@ done: } static int mma8452_reg_access_dbg(struct iio_dev *indio_dev, - unsigned reg, unsigned writeval, - unsigned *readval) + unsigned int reg, unsigned int writeval, + unsigned int *readval) { int ret; struct mma8452_data *data = iio_priv(indio_dev); @@ -1222,96 +1290,87 @@ static const struct mma_chip_info mma_chip_info_table[] = { * g * N * 1000000 / 2048 for N = 2, 4, 8 and g=9.80665 */ .mma_scales = { {0, 2394}, {0, 4788}, {0, 9577} }, - .ev_cfg = MMA8452_TRANSIENT_CFG, - .ev_cfg_ele = MMA8452_TRANSIENT_CFG_ELE, - .ev_cfg_chan_shift = 1, - .ev_src = MMA8452_TRANSIENT_SRC, - .ev_src_xe = MMA8452_TRANSIENT_SRC_XTRANSE, - .ev_src_ye = MMA8452_TRANSIENT_SRC_YTRANSE, - .ev_src_ze = MMA8452_TRANSIENT_SRC_ZTRANSE, - .ev_ths = MMA8452_TRANSIENT_THS, - .ev_ths_mask = MMA8452_TRANSIENT_THS_MASK, - .ev_count = MMA8452_TRANSIENT_COUNT, + /* + * Although we enable the interrupt sources once and for + * all here the event detection itself is not enabled until + * userspace asks for it by mma8452_write_event_config() + */ + .all_events = MMA8452_INT_DRDY | + MMA8452_INT_TRANS | + MMA8452_INT_FF_MT, + .enabled_events = MMA8452_INT_TRANS | + MMA8452_INT_FF_MT, }, [mma8452] = { .chip_id = MMA8452_DEVICE_ID, .channels = mma8452_channels, .num_channels = ARRAY_SIZE(mma8452_channels), .mma_scales = { {0, 9577}, {0, 19154}, {0, 38307} }, - .ev_cfg = MMA8452_TRANSIENT_CFG, - .ev_cfg_ele = MMA8452_TRANSIENT_CFG_ELE, - .ev_cfg_chan_shift = 1, - .ev_src = MMA8452_TRANSIENT_SRC, - .ev_src_xe = MMA8452_TRANSIENT_SRC_XTRANSE, - .ev_src_ye = MMA8452_TRANSIENT_SRC_YTRANSE, - .ev_src_ze = MMA8452_TRANSIENT_SRC_ZTRANSE, - .ev_ths = MMA8452_TRANSIENT_THS, - .ev_ths_mask = MMA8452_TRANSIENT_THS_MASK, - .ev_count = MMA8452_TRANSIENT_COUNT, + /* + * Although we enable the interrupt sources once and for + * all here the event detection itself is not enabled until + * userspace asks for it by mma8452_write_event_config() + */ + .all_events = MMA8452_INT_DRDY | + MMA8452_INT_TRANS | + MMA8452_INT_FF_MT, + .enabled_events = MMA8452_INT_TRANS | + MMA8452_INT_FF_MT, }, [mma8453] = { .chip_id = MMA8453_DEVICE_ID, .channels = mma8453_channels, .num_channels = ARRAY_SIZE(mma8453_channels), .mma_scales = { {0, 38307}, {0, 76614}, {0, 153228} }, - .ev_cfg = MMA8452_TRANSIENT_CFG, - .ev_cfg_ele = MMA8452_TRANSIENT_CFG_ELE, - .ev_cfg_chan_shift = 1, - .ev_src = MMA8452_TRANSIENT_SRC, - .ev_src_xe = MMA8452_TRANSIENT_SRC_XTRANSE, - .ev_src_ye = MMA8452_TRANSIENT_SRC_YTRANSE, - .ev_src_ze = MMA8452_TRANSIENT_SRC_ZTRANSE, - .ev_ths = MMA8452_TRANSIENT_THS, - .ev_ths_mask = MMA8452_TRANSIENT_THS_MASK, - .ev_count = MMA8452_TRANSIENT_COUNT, + /* + * Although we enable the interrupt sources once and for + * all here the event detection itself is not enabled until + * userspace asks for it by mma8452_write_event_config() + */ + .all_events = MMA8452_INT_DRDY | + MMA8452_INT_TRANS | + MMA8452_INT_FF_MT, + .enabled_events = MMA8452_INT_TRANS | + MMA8452_INT_FF_MT, }, [mma8652] = { .chip_id = MMA8652_DEVICE_ID, .channels = mma8652_channels, .num_channels = ARRAY_SIZE(mma8652_channels), .mma_scales = { {0, 9577}, {0, 19154}, {0, 38307} }, - .ev_cfg = MMA8452_FF_MT_CFG, - .ev_cfg_ele = MMA8452_FF_MT_CFG_ELE, - .ev_cfg_chan_shift = 3, - .ev_src = MMA8452_FF_MT_SRC, - .ev_src_xe = MMA8452_FF_MT_SRC_XHE, - .ev_src_ye = MMA8452_FF_MT_SRC_YHE, - .ev_src_ze = MMA8452_FF_MT_SRC_ZHE, - .ev_ths = MMA8452_FF_MT_THS, - .ev_ths_mask = MMA8452_FF_MT_THS_MASK, - .ev_count = MMA8452_FF_MT_COUNT, + .all_events = MMA8452_INT_DRDY | + MMA8452_INT_FF_MT, + .enabled_events = MMA8452_INT_FF_MT, }, [mma8653] = { .chip_id = MMA8653_DEVICE_ID, .channels = mma8653_channels, .num_channels = ARRAY_SIZE(mma8653_channels), .mma_scales = { {0, 38307}, {0, 76614}, {0, 153228} }, - .ev_cfg = MMA8452_FF_MT_CFG, - .ev_cfg_ele = MMA8452_FF_MT_CFG_ELE, - .ev_cfg_chan_shift = 3, - .ev_src = MMA8452_FF_MT_SRC, - .ev_src_xe = MMA8452_FF_MT_SRC_XHE, - .ev_src_ye = MMA8452_FF_MT_SRC_YHE, - .ev_src_ze = MMA8452_FF_MT_SRC_ZHE, - .ev_ths = MMA8452_FF_MT_THS, - .ev_ths_mask = MMA8452_FF_MT_THS_MASK, - .ev_count = MMA8452_FF_MT_COUNT, + /* + * Although we enable the interrupt sources once and for + * all here the event detection itself is not enabled until + * userspace asks for it by mma8452_write_event_config() + */ + .all_events = MMA8452_INT_DRDY | + MMA8452_INT_FF_MT, + .enabled_events = MMA8452_INT_FF_MT, }, [fxls8471] = { .chip_id = FXLS8471_DEVICE_ID, .channels = mma8451_channels, .num_channels = ARRAY_SIZE(mma8451_channels), .mma_scales = { {0, 2394}, {0, 4788}, {0, 9577} }, - .ev_cfg = MMA8452_TRANSIENT_CFG, - .ev_cfg_ele = MMA8452_TRANSIENT_CFG_ELE, - .ev_cfg_chan_shift = 1, - .ev_src = MMA8452_TRANSIENT_SRC, - .ev_src_xe = MMA8452_TRANSIENT_SRC_XTRANSE, - .ev_src_ye = MMA8452_TRANSIENT_SRC_YTRANSE, - .ev_src_ze = MMA8452_TRANSIENT_SRC_ZTRANSE, - .ev_ths = MMA8452_TRANSIENT_THS, - .ev_ths_mask = MMA8452_TRANSIENT_THS_MASK, - .ev_count = MMA8452_TRANSIENT_COUNT, + /* + * Although we enable the interrupt sources once and for + * all here the event detection itself is not enabled until + * userspace asks for it by mma8452_write_event_config() + */ + .all_events = MMA8452_INT_DRDY | + MMA8452_INT_TRANS | + MMA8452_INT_FF_MT, + .enabled_events = MMA8452_INT_TRANS | + MMA8452_INT_FF_MT, }, }; @@ -1332,12 +1391,11 @@ static const struct iio_info mma8452_info = { .read_raw = &mma8452_read_raw, .write_raw = &mma8452_write_raw, .event_attrs = &mma8452_event_attribute_group, - .read_event_value = &mma8452_read_thresh, - .write_event_value = &mma8452_write_thresh, + .read_event_value = &mma8452_read_event_value, + .write_event_value = &mma8452_write_event_value, .read_event_config = &mma8452_read_event_config, .write_event_config = &mma8452_write_event_config, .debugfs_reg_access = &mma8452_reg_access_dbg, - .driver_module = THIS_MODULE, }; static const unsigned long mma8452_scan_masks[] = {0x7, 0}; @@ -1368,7 +1426,6 @@ static int mma8452_data_rdy_trigger_set_state(struct iio_trigger *trig, static const struct iio_trigger_ops mma8452_trigger_ops = { .set_trigger_state = mma8452_data_rdy_trigger_set_state, .validate_device = iio_trigger_validate_own_device, - .owner = THIS_MODULE, }; static int mma8452_trigger_setup(struct iio_dev *indio_dev) @@ -1509,16 +1566,6 @@ static int mma8452_probe(struct i2c_client *client, return ret; if (client->irq) { - /* - * Although we enable the interrupt sources once and for - * all here the event detection itself is not enabled until - * userspace asks for it by mma8452_write_event_config() - */ - int supported_interrupts = MMA8452_INT_DRDY | - MMA8452_INT_TRANS | - MMA8452_INT_FF_MT; - int enabled_interrupts = MMA8452_INT_TRANS | - MMA8452_INT_FF_MT; int irq2; irq2 = of_irq_get_byname(client->dev.of_node, "INT2"); @@ -1527,8 +1574,8 @@ static int mma8452_probe(struct i2c_client *client, dev_dbg(&client->dev, "using interrupt line INT2\n"); } else { ret = i2c_smbus_write_byte_data(client, - MMA8452_CTRL_REG5, - supported_interrupts); + MMA8452_CTRL_REG5, + data->chip_info->all_events); if (ret < 0) return ret; @@ -1536,8 +1583,8 @@ static int mma8452_probe(struct i2c_client *client, } ret = i2c_smbus_write_byte_data(client, - MMA8452_CTRL_REG4, - enabled_interrupts); + MMA8452_CTRL_REG4, + data->chip_info->enabled_events); if (ret < 0) return ret; diff --git a/drivers/iio/accel/mma9551.c b/drivers/iio/accel/mma9551.c index 1f53f08476f5..da7c21504f38 100644 --- a/drivers/iio/accel/mma9551.c +++ b/drivers/iio/accel/mma9551.c @@ -332,7 +332,6 @@ static const struct iio_chan_spec mma9551_channels[] = { }; static const struct iio_info mma9551_info = { - .driver_module = THIS_MODULE, .read_raw = mma9551_read_raw, .read_event_config = mma9551_read_event_config, .write_event_config = mma9551_write_event_config, diff --git a/drivers/iio/accel/mma9553.c b/drivers/iio/accel/mma9553.c index 36bf19733be0..b52a3f182190 100644 --- a/drivers/iio/accel/mma9553.c +++ b/drivers/iio/accel/mma9553.c @@ -987,7 +987,6 @@ static const struct iio_chan_spec mma9553_channels[] = { }; static const struct iio_info mma9553_info = { - .driver_module = THIS_MODULE, .read_raw = mma9553_read_raw, .write_raw = mma9553_write_raw, .read_event_config = mma9553_read_event_config, diff --git a/drivers/iio/accel/mxc4005.c b/drivers/iio/accel/mxc4005.c index c23f47af7256..58099e40d717 100644 --- a/drivers/iio/accel/mxc4005.c +++ b/drivers/iio/accel/mxc4005.c @@ -264,7 +264,6 @@ static int mxc4005_write_raw(struct iio_dev *indio_dev, } static const struct iio_info mxc4005_info = { - .driver_module = THIS_MODULE, .read_raw = mxc4005_read_raw, .write_raw = mxc4005_write_raw, .attrs = &mxc4005_attrs_group, @@ -376,7 +375,6 @@ static int mxc4005_trigger_try_reen(struct iio_trigger *trig) static const struct iio_trigger_ops mxc4005_trigger_ops = { .set_trigger_state = mxc4005_set_trigger_state, .try_reenable = mxc4005_trigger_try_reen, - .owner = THIS_MODULE, }; static int mxc4005_chip_init(struct mxc4005_data *data) diff --git a/drivers/iio/accel/mxc6255.c b/drivers/iio/accel/mxc6255.c index 0abad6948201..ddd50d1781c5 100644 --- a/drivers/iio/accel/mxc6255.c +++ b/drivers/iio/accel/mxc6255.c @@ -78,7 +78,6 @@ static int mxc6255_read_raw(struct iio_dev *indio_dev, } static const struct iio_info mxc6255_info = { - .driver_module = THIS_MODULE, .read_raw = mxc6255_read_raw, }; diff --git a/drivers/iio/accel/sca3000.c b/drivers/iio/accel/sca3000.c index 39ab210c44f6..f33dadf7b262 100644 --- a/drivers/iio/accel/sca3000.c +++ b/drivers/iio/accel/sca3000.c @@ -1454,7 +1454,6 @@ static const struct iio_info sca3000_info = { .write_event_value = &sca3000_write_event_value, .read_event_config = &sca3000_read_event_config, .write_event_config = &sca3000_write_event_config, - .driver_module = THIS_MODULE, }; static int sca3000_probe(struct spi_device *spi) diff --git a/drivers/iio/accel/st_accel.h b/drivers/iio/accel/st_accel.h index 0fe521609a3a..2f931e4837e5 100644 --- a/drivers/iio/accel/st_accel.h +++ b/drivers/iio/accel/st_accel.h @@ -32,6 +32,8 @@ enum st_accel_type { H3LIS331DL, LIS331DL, LIS3LV02DL, + LIS2DW12, + LIS3DHH, ST_ACCEL_MAX, }; @@ -52,6 +54,8 @@ enum st_accel_type { #define LIS2DH12_ACCEL_DEV_NAME "lis2dh12_accel" #define LIS3L02DQ_ACCEL_DEV_NAME "lis3l02dq" #define LNG2DM_ACCEL_DEV_NAME "lng2dm" +#define LIS2DW12_ACCEL_DEV_NAME "lis2dw12" +#define LIS3DHH_ACCEL_DEV_NAME "lis3dhh" /** * struct st_sensors_platform_data - default accel platform data diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c index 752856b3a849..460aa58e0159 100644 --- a/drivers/iio/accel/st_accel_core.c +++ b/drivers/iio/accel/st_accel_core.c @@ -159,12 +159,16 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = { .mask = 0x80, }, .drdy_irq = { - .addr = 0x22, - .mask_int1 = 0x10, - .mask_int2 = 0x00, + .int1 = { + .addr = 0x22, + .mask = 0x10, + }, .addr_ihl = 0x25, .mask_ihl = 0x02, - .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR, + .stat_drdy = { + .addr = ST_SENSORS_DEFAULT_STAT_ADDR, + .mask = 0x07, + }, }, .sim = { .addr = 0x23, @@ -229,14 +233,24 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = { .mask = 0x80, }, .drdy_irq = { - .addr = 0x22, - .mask_int1 = 0x02, - .mask_int2 = 0x10, + .int1 = { + .addr = 0x22, + .mask = 0x02, + .addr_od = 0x22, + .mask_od = 0x40, + }, + .int2 = { + .addr = 0x22, + .mask = 0x10, + .addr_od = 0x22, + .mask_od = 0x40, + }, .addr_ihl = 0x22, .mask_ihl = 0x80, - .addr_od = 0x22, - .mask_od = 0x40, - .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR, + .stat_drdy = { + .addr = ST_SENSORS_DEFAULT_STAT_ADDR, + .mask = 0x07, + }, }, .sim = { .addr = 0x23, @@ -313,12 +327,16 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = { .mask = 0x08, }, .drdy_irq = { - .addr = 0x23, - .mask_int1 = 0x80, - .mask_int2 = 0x00, + .int1 = { + .addr = 0x23, + .mask = 0x80, + }, .addr_ihl = 0x23, .mask_ihl = 0x40, - .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR, + .stat_drdy = { + .addr = ST_SENSORS_DEFAULT_STAT_ADDR, + .mask = 0x07, + }, .ig1 = { .en_addr = 0x23, .en_mask = 0x08, @@ -387,9 +405,14 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = { .mask = 0x01, }, .drdy_irq = { - .addr = 0x21, - .mask_int1 = 0x04, - .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR, + .int1 = { + .addr = 0x21, + .mask = 0x04, + }, + .stat_drdy = { + .addr = ST_SENSORS_DEFAULT_STAT_ADDR, + .mask = 0x07, + }, }, .sim = { .addr = 0x21, @@ -444,14 +467,24 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = { }, }, .drdy_irq = { - .addr = 0x22, - .mask_int1 = 0x04, - .mask_int2 = 0x20, + .int1 = { + .addr = 0x22, + .mask = 0x04, + .addr_od = 0x22, + .mask_od = 0x40, + }, + .int2 = { + .addr = 0x22, + .mask = 0x20, + .addr_od = 0x22, + .mask_od = 0x40, + }, .addr_ihl = 0x22, .mask_ihl = 0x80, - .addr_od = 0x22, - .mask_od = 0x40, - .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR, + .stat_drdy = { + .addr = ST_SENSORS_DEFAULT_STAT_ADDR, + .mask = 0x07, + }, }, .sim = { .addr = 0x21, @@ -513,9 +546,14 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = { .mask = 0x80, }, .drdy_irq = { - .addr = 0x22, - .mask_int1 = 0x02, - .mask_int2 = 0x10, + .int1 = { + .addr = 0x22, + .mask = 0x02, + }, + .int2 = { + .addr = 0x22, + .mask = 0x10, + }, .addr_ihl = 0x22, .mask_ihl = 0x80, }, @@ -567,9 +605,14 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = { .bdu = { }, .drdy_irq = { - .addr = 0x21, - .mask_int1 = 0x04, - .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR, + .int1 = { + .addr = 0x21, + .mask = 0x04, + }, + .stat_drdy = { + .addr = ST_SENSORS_DEFAULT_STAT_ADDR, + .mask = 0x07, + }, }, .sim = { .addr = 0x21, @@ -635,12 +678,16 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = { }, }, .drdy_irq = { - .addr = 0x22, - .mask_int1 = 0x10, - .mask_int2 = 0x00, + .int1 = { + .addr = 0x22, + .mask = 0x10, + }, .addr_ihl = 0x25, .mask_ihl = 0x02, - .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR, + .stat_drdy = { + .addr = ST_SENSORS_DEFAULT_STAT_ADDR, + .mask = 0x07, + }, }, .sim = { .addr = 0x23, @@ -649,6 +696,139 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = { .multi_read_bit = true, .bootime = 2, }, + { + .wai = 0x44, + .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS, + .sensors_supported = { + [0] = LIS2DW12_ACCEL_DEV_NAME, + }, + .ch = (struct iio_chan_spec *)st_accel_12bit_channels, + .odr = { + .addr = 0x20, + .mask = 0xf0, + .odr_avl = { + { .hz = 1, .value = 0x01, }, + { .hz = 12, .value = 0x02, }, + { .hz = 25, .value = 0x03, }, + { .hz = 50, .value = 0x04, }, + { .hz = 100, .value = 0x05, }, + { .hz = 200, .value = 0x06, }, + }, + }, + .pw = { + .addr = 0x20, + .mask = 0xf0, + .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE, + }, + .fs = { + .addr = 0x25, + .mask = 0x30, + .fs_avl = { + [0] = { + .num = ST_ACCEL_FS_AVL_2G, + .value = 0x00, + .gain = IIO_G_TO_M_S_2(976), + }, + [1] = { + .num = ST_ACCEL_FS_AVL_4G, + .value = 0x01, + .gain = IIO_G_TO_M_S_2(1952), + }, + [2] = { + .num = ST_ACCEL_FS_AVL_8G, + .value = 0x02, + .gain = IIO_G_TO_M_S_2(3904), + }, + [3] = { + .num = ST_ACCEL_FS_AVL_16G, + .value = 0x03, + .gain = IIO_G_TO_M_S_2(7808), + }, + }, + }, + .bdu = { + .addr = 0x21, + .mask = 0x08, + }, + .drdy_irq = { + .int1 = { + .addr = 0x23, + .mask = 0x01, + .addr_od = 0x22, + .mask_od = 0x20, + }, + .int2 = { + .addr = 0x24, + .mask = 0x01, + .addr_od = 0x22, + .mask_od = 0x20, + }, + .addr_ihl = 0x22, + .mask_ihl = 0x08, + .stat_drdy = { + .addr = ST_SENSORS_DEFAULT_STAT_ADDR, + .mask = 0x01, + }, + }, + .sim = { + .addr = 0x21, + .value = BIT(0), + }, + .multi_read_bit = false, + .bootime = 2, + }, + { + .wai = 0x11, + .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS, + .sensors_supported = { + [0] = LIS3DHH_ACCEL_DEV_NAME, + }, + .ch = (struct iio_chan_spec *)st_accel_16bit_channels, + .odr = { + /* just ODR = 1100Hz available */ + .odr_avl = { + { .hz = 1100, .value = 0x00, }, + }, + }, + .pw = { + .addr = 0x20, + .mask = 0x80, + .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE, + .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE, + }, + .fs = { + .fs_avl = { + [0] = { + .num = ST_ACCEL_FS_AVL_2G, + .gain = IIO_G_TO_M_S_2(76), + }, + }, + }, + .bdu = { + .addr = 0x20, + .mask = 0x01, + }, + .drdy_irq = { + .int1 = { + .addr = 0x21, + .mask = 0x80, + .addr_od = 0x23, + .mask_od = 0x04, + }, + .int2 = { + .addr = 0x22, + .mask = 0x80, + .addr_od = 0x23, + .mask_od = 0x08, + }, + .stat_drdy = { + .addr = ST_SENSORS_DEFAULT_STAT_ADDR, + .mask = 0x07, + }, + }, + .multi_read_bit = false, + .bootime = 2, + }, }; static int st_accel_read_raw(struct iio_dev *indio_dev, @@ -721,7 +901,6 @@ static const struct attribute_group st_accel_attribute_group = { }; static const struct iio_info accel_info = { - .driver_module = THIS_MODULE, .attrs = &st_accel_attribute_group, .read_raw = &st_accel_read_raw, .write_raw = &st_accel_write_raw, @@ -730,7 +909,6 @@ static const struct iio_info accel_info = { #ifdef CONFIG_IIO_TRIGGER static const struct iio_trigger_ops st_accel_trigger_ops = { - .owner = THIS_MODULE, .set_trigger_state = ST_ACCEL_TRIGGER_SET_STATE, .validate_device = st_sensors_validate_device, }; diff --git a/drivers/iio/accel/st_accel_i2c.c b/drivers/iio/accel/st_accel_i2c.c index 18cafb9f2468..363429b5686c 100644 --- a/drivers/iio/accel/st_accel_i2c.c +++ b/drivers/iio/accel/st_accel_i2c.c @@ -94,6 +94,10 @@ static const struct of_device_id st_accel_of_match[] = { .compatible = "st,lng2dm-accel", .data = LNG2DM_ACCEL_DEV_NAME, }, + { + .compatible = "st,lis2dw12", + .data = LIS2DW12_ACCEL_DEV_NAME, + }, {}, }; MODULE_DEVICE_TABLE(of, st_accel_of_match); @@ -129,6 +133,7 @@ static const struct i2c_device_id st_accel_id_table[] = { { H3LIS331DL_ACCEL_DEV_NAME, H3LIS331DL }, { LIS331DL_ACCEL_DEV_NAME, LIS331DL }, { LIS3LV02DL_ACCEL_DEV_NAME, LIS3LV02DL }, + { LIS2DW12_ACCEL_DEV_NAME, LIS2DW12 }, {}, }; MODULE_DEVICE_TABLE(i2c, st_accel_id_table); diff --git a/drivers/iio/accel/st_accel_spi.c b/drivers/iio/accel/st_accel_spi.c index 915fa49085f7..dcc9bd243a52 100644 --- a/drivers/iio/accel/st_accel_spi.c +++ b/drivers/iio/accel/st_accel_spi.c @@ -82,6 +82,14 @@ static const struct of_device_id st_accel_of_match[] = { .compatible = "st,lis331dl-accel", .data = LIS331DL_ACCEL_DEV_NAME, }, + { + .compatible = "st,lis2dw12", + .data = LIS2DW12_ACCEL_DEV_NAME, + }, + { + .compatible = "st,lis3dhh", + .data = LIS3DHH_ACCEL_DEV_NAME, + }, {} }; MODULE_DEVICE_TABLE(of, st_accel_of_match); @@ -133,6 +141,8 @@ static const struct spi_device_id st_accel_id_table[] = { { H3LIS331DL_ACCEL_DEV_NAME }, { LIS331DL_ACCEL_DEV_NAME }, { LIS3LV02DL_ACCEL_DEV_NAME }, + { LIS2DW12_ACCEL_DEV_NAME }, + { LIS3DHH_ACCEL_DEV_NAME }, {}, }; MODULE_DEVICE_TABLE(spi, st_accel_id_table); diff --git a/drivers/iio/accel/stk8312.c b/drivers/iio/accel/stk8312.c index e31023dc5f1b..cacc0da2f874 100644 --- a/drivers/iio/accel/stk8312.c +++ b/drivers/iio/accel/stk8312.c @@ -237,7 +237,6 @@ static int stk8312_data_rdy_trigger_set_state(struct iio_trigger *trig, static const struct iio_trigger_ops stk8312_trigger_ops = { .set_trigger_state = stk8312_data_rdy_trigger_set_state, - .owner = THIS_MODULE, }; static int stk8312_set_sample_rate(struct stk8312_data *data, u8 rate) @@ -421,7 +420,6 @@ static int stk8312_write_raw(struct iio_dev *indio_dev, } static const struct iio_info stk8312_info = { - .driver_module = THIS_MODULE, .read_raw = stk8312_read_raw, .write_raw = stk8312_write_raw, .attrs = &stk8312_attribute_group, diff --git a/drivers/iio/accel/stk8ba50.c b/drivers/iio/accel/stk8ba50.c index 300d955bad00..576b6b140f08 100644 --- a/drivers/iio/accel/stk8ba50.c +++ b/drivers/iio/accel/stk8ba50.c @@ -179,7 +179,6 @@ static int stk8ba50_data_rdy_trigger_set_state(struct iio_trigger *trig, static const struct iio_trigger_ops stk8ba50_trigger_ops = { .set_trigger_state = stk8ba50_data_rdy_trigger_set_state, - .owner = THIS_MODULE, }; static int stk8ba50_set_power(struct stk8ba50_data *data, bool mode) @@ -307,7 +306,6 @@ static int stk8ba50_write_raw(struct iio_dev *indio_dev, } static const struct iio_info stk8ba50_info = { - .driver_module = THIS_MODULE, .read_raw = stk8ba50_read_raw, .write_raw = stk8ba50_write_raw, .attrs = &stk8ba50_attribute_group, diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 1d13bf03c758..ef86296b8b0d 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -477,12 +477,13 @@ config MAX9611 called max9611. config MCP320X - tristate "Microchip Technology MCP3x01/02/04/08" + tristate "Microchip Technology MCP3x01/02/04/08 and MCP3550/1/3" depends on SPI help Say yes here to build support for Microchip Technology's MCP3001, MCP3002, MCP3004, MCP3008, MCP3201, MCP3202, MCP3204, - MCP3208 or MCP3301 analog to digital converter. + MCP3208, MCP3301, MCP3550, MCP3551 and MCP3553 analog to digital + converters. This driver can also be built as a module. If so, the module will be called mcp320x. @@ -595,7 +596,7 @@ config QCOM_SPMI_VADC config RCAR_GYRO_ADC tristate "Renesas R-Car GyroADC driver" - depends on ARCH_RCAR_GEN2 || (ARM && COMPILE_TEST) + depends on ARCH_RCAR_GEN2 || COMPILE_TEST help Say yes here to build support for the GyroADC found in Renesas R-Car Gen2 SoCs. This block is a simple SPI offload engine for diff --git a/drivers/iio/adc/ad7266.c b/drivers/iio/adc/ad7266.c index b8d5cfd57ec4..605eb5e7e829 100644 --- a/drivers/iio/adc/ad7266.c +++ b/drivers/iio/adc/ad7266.c @@ -280,7 +280,6 @@ static AD7266_DECLARE_DIFF_CHANNELS_FIXED(u, 'u'); static const struct iio_info ad7266_info = { .read_raw = &ad7266_read_raw, .update_scan_mode = &ad7266_update_scan_mode, - .driver_module = THIS_MODULE, }; static const unsigned long ad7266_available_scan_masks[] = { diff --git a/drivers/iio/adc/ad7291.c b/drivers/iio/adc/ad7291.c index 1d90b02732bb..a862b5d8fb4b 100644 --- a/drivers/iio/adc/ad7291.c +++ b/drivers/iio/adc/ad7291.c @@ -461,7 +461,6 @@ static const struct iio_info ad7291_info = { .write_event_config = &ad7291_write_event_config, .read_event_value = &ad7291_read_event_value, .write_event_value = &ad7291_write_event_value, - .driver_module = THIS_MODULE, }; static int ad7291_probe(struct i2c_client *client, diff --git a/drivers/iio/adc/ad7298.c b/drivers/iio/adc/ad7298.c index e399bf04c73a..2b20c6c8ec7f 100644 --- a/drivers/iio/adc/ad7298.c +++ b/drivers/iio/adc/ad7298.c @@ -280,7 +280,6 @@ static int ad7298_read_raw(struct iio_dev *indio_dev, static const struct iio_info ad7298_info = { .read_raw = &ad7298_read_raw, .update_scan_mode = ad7298_update_scan_mode, - .driver_module = THIS_MODULE, }; static int ad7298_probe(struct spi_device *spi) diff --git a/drivers/iio/adc/ad7476.c b/drivers/iio/adc/ad7476.c index b7ecf9aab90f..b7706bf10ffe 100644 --- a/drivers/iio/adc/ad7476.c +++ b/drivers/iio/adc/ad7476.c @@ -195,7 +195,6 @@ static const struct ad7476_chip_info ad7476_chip_info_tbl[] = { }; static const struct iio_info ad7476_info = { - .driver_module = THIS_MODULE, .read_raw = &ad7476_read_raw, }; diff --git a/drivers/iio/adc/ad7766.c b/drivers/iio/adc/ad7766.c index ce45037295d8..3ae14fc8c649 100644 --- a/drivers/iio/adc/ad7766.c +++ b/drivers/iio/adc/ad7766.c @@ -185,7 +185,6 @@ static const struct iio_buffer_setup_ops ad7766_buffer_setup_ops = { }; static const struct iio_info ad7766_info = { - .driver_module = THIS_MODULE, .read_raw = &ad7766_read_raw, }; @@ -208,7 +207,6 @@ static int ad7766_set_trigger_state(struct iio_trigger *trig, bool enable) } static const struct iio_trigger_ops ad7766_trigger_ops = { - .owner = THIS_MODULE, .set_trigger_state = ad7766_set_trigger_state, .validate_device = iio_trigger_validate_own_device, }; diff --git a/drivers/iio/adc/ad7791.c b/drivers/iio/adc/ad7791.c index 34e353c43ac8..70fbf92f9827 100644 --- a/drivers/iio/adc/ad7791.c +++ b/drivers/iio/adc/ad7791.c @@ -308,13 +308,11 @@ static const struct iio_info ad7791_info = { .read_raw = &ad7791_read_raw, .attrs = &ad7791_attribute_group, .validate_trigger = ad_sd_validate_trigger, - .driver_module = THIS_MODULE, }; static const struct iio_info ad7791_no_filter_info = { .read_raw = &ad7791_read_raw, .validate_trigger = ad_sd_validate_trigger, - .driver_module = THIS_MODULE, }; static int ad7791_setup(struct ad7791_state *st, diff --git a/drivers/iio/adc/ad7793.c b/drivers/iio/adc/ad7793.c index 47c3d7f32900..801afb61310b 100644 --- a/drivers/iio/adc/ad7793.c +++ b/drivers/iio/adc/ad7793.c @@ -563,7 +563,6 @@ static const struct iio_info ad7793_info = { .write_raw_get_fmt = &ad7793_write_raw_get_fmt, .attrs = &ad7793_attribute_group, .validate_trigger = ad_sd_validate_trigger, - .driver_module = THIS_MODULE, }; static const struct iio_info ad7797_info = { @@ -572,7 +571,6 @@ static const struct iio_info ad7797_info = { .write_raw_get_fmt = &ad7793_write_raw_get_fmt, .attrs = &ad7793_attribute_group, .validate_trigger = ad_sd_validate_trigger, - .driver_module = THIS_MODULE, }; #define DECLARE_AD7793_CHANNELS(_name, _b, _sb, _s) \ diff --git a/drivers/iio/adc/ad7887.c b/drivers/iio/adc/ad7887.c index 7a483bfbd70c..205c0f1761aa 100644 --- a/drivers/iio/adc/ad7887.c +++ b/drivers/iio/adc/ad7887.c @@ -229,7 +229,6 @@ static const struct ad7887_chip_info ad7887_chip_info_tbl[] = { static const struct iio_info ad7887_info = { .read_raw = &ad7887_read_raw, - .driver_module = THIS_MODULE, }; static int ad7887_probe(struct spi_device *spi) diff --git a/drivers/iio/adc/ad7923.c b/drivers/iio/adc/ad7923.c index 77a675e11ebb..ffb7e089969c 100644 --- a/drivers/iio/adc/ad7923.c +++ b/drivers/iio/adc/ad7923.c @@ -262,7 +262,6 @@ static int ad7923_read_raw(struct iio_dev *indio_dev, static const struct iio_info ad7923_info = { .read_raw = &ad7923_read_raw, .update_scan_mode = ad7923_update_scan_mode, - .driver_module = THIS_MODULE, }; static int ad7923_probe(struct spi_device *spi) diff --git a/drivers/iio/adc/ad799x.c b/drivers/iio/adc/ad799x.c index 22426ae4af97..e1da67d5ee22 100644 --- a/drivers/iio/adc/ad799x.c +++ b/drivers/iio/adc/ad799x.c @@ -526,13 +526,11 @@ static const struct attribute_group ad799x_event_attrs_group = { static const struct iio_info ad7991_info = { .read_raw = &ad799x_read_raw, - .driver_module = THIS_MODULE, .update_scan_mode = ad799x_update_scan_mode, }; static const struct iio_info ad7993_4_7_8_noirq_info = { .read_raw = &ad799x_read_raw, - .driver_module = THIS_MODULE, .update_scan_mode = ad799x_update_scan_mode, }; @@ -543,7 +541,6 @@ static const struct iio_info ad7993_4_7_8_irq_info = { .write_event_config = &ad799x_write_event_config, .read_event_value = &ad799x_read_event_value, .write_event_value = &ad799x_write_event_value, - .driver_module = THIS_MODULE, .update_scan_mode = ad799x_update_scan_mode, }; diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c index 22c4c17cd996..cf1b048b0665 100644 --- a/drivers/iio/adc/ad_sigma_delta.c +++ b/drivers/iio/adc/ad_sigma_delta.c @@ -463,7 +463,6 @@ int ad_sd_validate_trigger(struct iio_dev *indio_dev, struct iio_trigger *trig) EXPORT_SYMBOL_GPL(ad_sd_validate_trigger); static const struct iio_trigger_ops ad_sd_trigger_ops = { - .owner = THIS_MODULE, }; static int ad_sd_probe_trigger(struct iio_dev *indio_dev) diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c index c02b23d675cb..8a958d5f1905 100644 --- a/drivers/iio/adc/aspeed_adc.c +++ b/drivers/iio/adc/aspeed_adc.c @@ -165,7 +165,6 @@ static int aspeed_adc_reg_access(struct iio_dev *indio_dev, } static const struct iio_info aspeed_adc_iio_info = { - .driver_module = THIS_MODULE, .read_raw = aspeed_adc_read_raw, .write_raw = aspeed_adc_write_raw, .debugfs_reg_access = aspeed_adc_reg_access, diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c index a70ef7fec95f..755a493c2a2c 100644 --- a/drivers/iio/adc/at91-sama5d2_adc.c +++ b/drivers/iio/adc/at91-sama5d2_adc.c @@ -348,7 +348,6 @@ static int at91_adc_reenable_trigger(struct iio_trigger *trig) } static const struct iio_trigger_ops at91_adc_trigger_ops = { - .owner = THIS_MODULE, .set_trigger_state = &at91_adc_configure_trigger, .try_reenable = &at91_adc_reenable_trigger, }; @@ -584,7 +583,6 @@ static int at91_adc_write_raw(struct iio_dev *indio_dev, static const struct iio_info at91_adc_info = { .read_raw = &at91_adc_read_raw, .write_raw = &at91_adc_write_raw, - .driver_module = THIS_MODULE, }; static void at91_adc_hw_init(struct at91_adc_state *st) diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index 15109728cae7..3836d4222a3e 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -594,7 +594,6 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state) } static const struct iio_trigger_ops at91_adc_trigger_ops = { - .owner = THIS_MODULE, .set_trigger_state = &at91_adc_configure_trigger, }; @@ -976,7 +975,6 @@ static int at91_adc_probe_pdata(struct at91_adc_state *st, } static const struct iio_info at91_adc_info = { - .driver_module = THIS_MODULE, .read_raw = &at91_adc_read_raw, }; diff --git a/drivers/iio/adc/axp20x_adc.c b/drivers/iio/adc/axp20x_adc.c index 11e177180ea0..a30a97245e91 100644 --- a/drivers/iio/adc/axp20x_adc.c +++ b/drivers/iio/adc/axp20x_adc.c @@ -464,12 +464,10 @@ static int axp20x_write_raw(struct iio_dev *indio_dev, static const struct iio_info axp20x_adc_iio_info = { .read_raw = axp20x_read_raw, .write_raw = axp20x_write_raw, - .driver_module = THIS_MODULE, }; static const struct iio_info axp22x_adc_iio_info = { .read_raw = axp22x_read_raw, - .driver_module = THIS_MODULE, }; static int axp20x_adc_rate(int rate) diff --git a/drivers/iio/adc/axp288_adc.c b/drivers/iio/adc/axp288_adc.c index 462a99c13e7a..60c9e853dd81 100644 --- a/drivers/iio/adc/axp288_adc.c +++ b/drivers/iio/adc/axp288_adc.c @@ -183,7 +183,6 @@ static int axp288_adc_set_state(struct regmap *regmap) static const struct iio_info axp288_adc_iio_info = { .read_raw = &axp288_adc_read_raw, - .driver_module = THIS_MODULE, }; static int axp288_adc_probe(struct platform_device *pdev) diff --git a/drivers/iio/adc/bcm_iproc_adc.c b/drivers/iio/adc/bcm_iproc_adc.c index 7f4f9c4150e3..7af59a4bbd8d 100644 --- a/drivers/iio/adc/bcm_iproc_adc.c +++ b/drivers/iio/adc/bcm_iproc_adc.c @@ -492,7 +492,6 @@ static int iproc_adc_read_raw(struct iio_dev *indio_dev, static const struct iio_info iproc_adc_iio_info = { .read_raw = &iproc_adc_read_raw, - .driver_module = THIS_MODULE, }; #define IPROC_ADC_CHANNEL(_index, _id) { \ diff --git a/drivers/iio/adc/berlin2-adc.c b/drivers/iio/adc/berlin2-adc.c index 71c806ecc722..72d8fa94ab31 100644 --- a/drivers/iio/adc/berlin2-adc.c +++ b/drivers/iio/adc/berlin2-adc.c @@ -277,7 +277,6 @@ static irqreturn_t berlin2_adc_tsen_irq(int irq, void *private) } static const struct iio_info berlin2_adc_info = { - .driver_module = THIS_MODULE, .read_raw = berlin2_adc_read_raw, }; diff --git a/drivers/iio/adc/cc10001_adc.c b/drivers/iio/adc/cc10001_adc.c index 91636c0ba5b5..707d8b24b072 100644 --- a/drivers/iio/adc/cc10001_adc.c +++ b/drivers/iio/adc/cc10001_adc.c @@ -262,7 +262,6 @@ static int cc10001_update_scan_mode(struct iio_dev *indio_dev, } static const struct iio_info cc10001_adc_info = { - .driver_module = THIS_MODULE, .read_raw = &cc10001_adc_read_raw, .update_scan_mode = &cc10001_update_scan_mode, }; diff --git a/drivers/iio/adc/cpcap-adc.c b/drivers/iio/adc/cpcap-adc.c index 6e419d5a7c14..3576ec73ec23 100644 --- a/drivers/iio/adc/cpcap-adc.c +++ b/drivers/iio/adc/cpcap-adc.c @@ -932,7 +932,6 @@ err_unlock: static const struct iio_info cpcap_adc_info = { .read_raw = &cpcap_adc_read, - .driver_module = THIS_MODULE, }; /* diff --git a/drivers/iio/adc/da9150-gpadc.c b/drivers/iio/adc/da9150-gpadc.c index 3445107e10b7..0a5d9ce79164 100644 --- a/drivers/iio/adc/da9150-gpadc.c +++ b/drivers/iio/adc/da9150-gpadc.c @@ -249,7 +249,6 @@ static int da9150_gpadc_read_raw(struct iio_dev *indio_dev, static const struct iio_info da9150_gpadc_info = { .read_raw = &da9150_gpadc_read_raw, - .driver_module = THIS_MODULE, }; #define DA9150_GPADC_CHANNEL(_id, _hw_id, _type, chan_info, \ diff --git a/drivers/iio/adc/dln2-adc.c b/drivers/iio/adc/dln2-adc.c index ab8d6aed5085..c64c6675cae6 100644 --- a/drivers/iio/adc/dln2-adc.c +++ b/drivers/iio/adc/dln2-adc.c @@ -479,7 +479,6 @@ static const struct iio_info dln2_adc_info = { .read_raw = dln2_adc_read_raw, .write_raw = dln2_adc_write_raw, .update_scan_mode = dln2_update_scan_mode, - .driver_module = THIS_MODULE, }; static irqreturn_t dln2_adc_trigger_h(int irq, void *p) @@ -604,10 +603,6 @@ static void dln2_adc_event(struct platform_device *pdev, u16 echo, iio_trigger_poll(dln2->trig); } -static const struct iio_trigger_ops dln2_adc_trigger_ops = { - .owner = THIS_MODULE, -}; - static int dln2_adc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -665,7 +660,6 @@ static int dln2_adc_probe(struct platform_device *pdev) dev_err(dev, "failed to allocate trigger\n"); return -ENOMEM; } - dln2->trig->ops = &dln2_adc_trigger_ops; iio_trigger_set_drvdata(dln2->trig, dln2); devm_iio_trigger_register(dev, dln2->trig); iio_trigger_set_immutable(indio_dev, dln2->trig); diff --git a/drivers/iio/adc/envelope-detector.c b/drivers/iio/adc/envelope-detector.c index fef15c0d7c9c..4ebda8ab54fe 100644 --- a/drivers/iio/adc/envelope-detector.c +++ b/drivers/iio/adc/envelope-detector.c @@ -322,7 +322,6 @@ static const struct iio_chan_spec envelope_detector_iio_channel = { static const struct iio_info envelope_detector_info = { .read_raw = &envelope_detector_read_raw, - .driver_module = THIS_MODULE, }; static int envelope_detector_probe(struct platform_device *pdev) diff --git a/drivers/iio/adc/ep93xx_adc.c b/drivers/iio/adc/ep93xx_adc.c index a179ac476c6d..81c901507ad2 100644 --- a/drivers/iio/adc/ep93xx_adc.c +++ b/drivers/iio/adc/ep93xx_adc.c @@ -150,7 +150,6 @@ static int ep93xx_read_raw(struct iio_dev *iiodev, } static const struct iio_info ep93xx_adc_info = { - .driver_module = THIS_MODULE, .read_raw = ep93xx_read_raw, }; diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c index 6c5a7be9f8c1..f10443f92e4c 100644 --- a/drivers/iio/adc/exynos_adc.c +++ b/drivers/iio/adc/exynos_adc.c @@ -657,7 +657,6 @@ static int exynos_adc_reg_access(struct iio_dev *indio_dev, static const struct iio_info exynos_adc_iio_info = { .read_raw = &exynos_read_raw, .debugfs_reg_access = &exynos_adc_reg_access, - .driver_module = THIS_MODULE, }; #define ADC_CHANNEL(_index, _id) { \ diff --git a/drivers/iio/adc/hi8435.c b/drivers/iio/adc/hi8435.c index adf7dc712937..6f6c9a348158 100644 --- a/drivers/iio/adc/hi8435.c +++ b/drivers/iio/adc/hi8435.c @@ -408,7 +408,6 @@ static const struct iio_chan_spec hi8435_channels[] = { }; static const struct iio_info hi8435_info = { - .driver_module = THIS_MODULE, .read_raw = hi8435_read_raw, .read_event_config = hi8435_read_event_config, .write_event_config = hi8435_write_event_config, diff --git a/drivers/iio/adc/hx711.c b/drivers/iio/adc/hx711.c index 27005d84ed73..d10b9f13d557 100644 --- a/drivers/iio/adc/hx711.c +++ b/drivers/iio/adc/hx711.c @@ -374,7 +374,6 @@ static const struct attribute_group hx711_attribute_group = { }; static const struct iio_info hx711_iio_info = { - .driver_module = THIS_MODULE, .read_raw = hx711_read_raw, .write_raw = hx711_write_raw, .write_raw_get_fmt = hx711_write_raw_get_fmt, diff --git a/drivers/iio/adc/imx7d_adc.c b/drivers/iio/adc/imx7d_adc.c index 254b29a68b9d..cfab31162845 100644 --- a/drivers/iio/adc/imx7d_adc.c +++ b/drivers/iio/adc/imx7d_adc.c @@ -412,7 +412,6 @@ static int imx7d_adc_reg_access(struct iio_dev *indio_dev, } static const struct iio_info imx7d_adc_iio_info = { - .driver_module = THIS_MODULE, .read_raw = &imx7d_adc_read_raw, .debugfs_reg_access = &imx7d_adc_reg_access, }; diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c index f387b972e4f4..84a43871f7dc 100644 --- a/drivers/iio/adc/ina2xx-adc.c +++ b/drivers/iio/adc/ina2xx-adc.c @@ -123,7 +123,7 @@ struct ina2xx_chip_info { struct task_struct *task; const struct ina2xx_config *config; struct mutex state_lock; - unsigned int shunt_resistor; + unsigned int shunt_resistor_uohm; int avg; int int_time_vbus; /* Bus voltage integration time uS */ int int_time_vshunt; /* Shunt voltage integration time uS */ @@ -436,7 +436,7 @@ static ssize_t ina2xx_allow_async_readout_store(struct device *dev, /* * Set current LSB to 1mA, shunt is in uOhms * (equation 13 in datasheet). We hardcode a Current_LSB - * of 1.0 x10-6. The only remaining parameter is RShunt. + * of 1.0 x10-3. The only remaining parameter is RShunt. * There is no need to expose the CALIBRATION register * to the user for now. But we need to reset this register * if the user updates RShunt after driver init, e.g upon @@ -445,7 +445,7 @@ static ssize_t ina2xx_allow_async_readout_store(struct device *dev, static int ina2xx_set_calibration(struct ina2xx_chip_info *chip) { u16 regval = DIV_ROUND_CLOSEST(chip->config->calibration_factor, - chip->shunt_resistor); + chip->shunt_resistor_uohm); return regmap_write(chip->regmap, INA2XX_CALIBRATION, regval); } @@ -455,7 +455,7 @@ static int set_shunt_resistor(struct ina2xx_chip_info *chip, unsigned int val) if (val <= 0 || val > chip->config->calibration_factor) return -EINVAL; - chip->shunt_resistor = val; + chip->shunt_resistor_uohm = val; return 0; } @@ -465,8 +465,9 @@ static ssize_t ina2xx_shunt_resistor_show(struct device *dev, char *buf) { struct ina2xx_chip_info *chip = iio_priv(dev_to_iio_dev(dev)); + int vals[2] = { chip->shunt_resistor_uohm, 1000000 }; - return sprintf(buf, "%d\n", chip->shunt_resistor); + return iio_format_value(buf, IIO_VAL_FRACTIONAL, 1, vals); } static ssize_t ina2xx_shunt_resistor_store(struct device *dev, @@ -474,14 +475,13 @@ static ssize_t ina2xx_shunt_resistor_store(struct device *dev, const char *buf, size_t len) { struct ina2xx_chip_info *chip = iio_priv(dev_to_iio_dev(dev)); - unsigned long val; - int ret; + int val, val_fract, ret; - ret = kstrtoul((const char *) buf, 10, &val); + ret = iio_str_to_fixpoint(buf, 100000, &val, &val_fract); if (ret) return ret; - ret = set_shunt_resistor(chip, val); + ret = set_shunt_resistor(chip, val * 1000000 + val_fract); if (ret) return ret; @@ -778,7 +778,6 @@ static const struct attribute_group ina226_attribute_group = { }; static const struct iio_info ina219_info = { - .driver_module = THIS_MODULE, .attrs = &ina219_attribute_group, .read_raw = ina2xx_read_raw, .write_raw = ina2xx_write_raw, @@ -786,7 +785,6 @@ static const struct iio_info ina219_info = { }; static const struct iio_info ina226_info = { - .driver_module = THIS_MODULE, .attrs = &ina226_attribute_group, .read_raw = ina2xx_read_raw, .write_raw = ina2xx_write_raw, diff --git a/drivers/iio/adc/lp8788_adc.c b/drivers/iio/adc/lp8788_adc.c index 152cfc8e1c7b..3bc4df916420 100644 --- a/drivers/iio/adc/lp8788_adc.c +++ b/drivers/iio/adc/lp8788_adc.c @@ -125,7 +125,6 @@ static int lp8788_adc_read_raw(struct iio_dev *indio_dev, static const struct iio_info lp8788_adc_info = { .read_raw = &lp8788_adc_read_raw, - .driver_module = THIS_MODULE, }; #define LP8788_CHAN(_id, _type) { \ diff --git a/drivers/iio/adc/lpc18xx_adc.c b/drivers/iio/adc/lpc18xx_adc.c index 3ef18f4b27f0..041dc4a3f66c 100644 --- a/drivers/iio/adc/lpc18xx_adc.c +++ b/drivers/iio/adc/lpc18xx_adc.c @@ -116,7 +116,6 @@ static int lpc18xx_adc_read_raw(struct iio_dev *indio_dev, static const struct iio_info lpc18xx_adc_info = { .read_raw = lpc18xx_adc_read_raw, - .driver_module = THIS_MODULE, }; static int lpc18xx_adc_probe(struct platform_device *pdev) diff --git a/drivers/iio/adc/lpc32xx_adc.c b/drivers/iio/adc/lpc32xx_adc.c index 6a5b9a9bc662..20b36690fa4f 100644 --- a/drivers/iio/adc/lpc32xx_adc.c +++ b/drivers/iio/adc/lpc32xx_adc.c @@ -104,7 +104,6 @@ static int lpc32xx_read_raw(struct iio_dev *indio_dev, static const struct iio_info lpc32xx_adc_iio_info = { .read_raw = &lpc32xx_read_raw, - .driver_module = THIS_MODULE, }; #define LPC32XX_ADC_CHANNEL(_index) { \ diff --git a/drivers/iio/adc/ltc2471.c b/drivers/iio/adc/ltc2471.c index 29b7ed60cdb0..b88102b751cf 100644 --- a/drivers/iio/adc/ltc2471.c +++ b/drivers/iio/adc/ltc2471.c @@ -98,7 +98,6 @@ static const struct iio_chan_spec ltc2473_channel[] = { static const struct iio_info ltc2471_info = { .read_raw = ltc2471_read_raw, - .driver_module = THIS_MODULE, }; static int ltc2471_i2c_probe(struct i2c_client *client, diff --git a/drivers/iio/adc/ltc2485.c b/drivers/iio/adc/ltc2485.c index eab91f12454a..b24c14037fd4 100644 --- a/drivers/iio/adc/ltc2485.c +++ b/drivers/iio/adc/ltc2485.c @@ -90,7 +90,6 @@ static const struct iio_chan_spec ltc2485_channel[] = { static const struct iio_info ltc2485_info = { .read_raw = ltc2485_read_raw, - .driver_module = THIS_MODULE, }; static int ltc2485_probe(struct i2c_client *client, diff --git a/drivers/iio/adc/ltc2497.c b/drivers/iio/adc/ltc2497.c index 5bf8011dcde9..f1f7cdf66fbd 100644 --- a/drivers/iio/adc/ltc2497.c +++ b/drivers/iio/adc/ltc2497.c @@ -186,7 +186,6 @@ static const struct iio_chan_spec ltc2497_channel[] = { static const struct iio_info ltc2497_info = { .read_raw = ltc2497_read_raw, - .driver_module = THIS_MODULE, }; static int ltc2497_probe(struct i2c_client *client, diff --git a/drivers/iio/adc/max1027.c b/drivers/iio/adc/max1027.c index ebc715927e63..375da6491499 100644 --- a/drivers/iio/adc/max1027.c +++ b/drivers/iio/adc/max1027.c @@ -381,13 +381,11 @@ static irqreturn_t max1027_trigger_handler(int irq, void *private) } static const struct iio_trigger_ops max1027_trigger_ops = { - .owner = THIS_MODULE, .validate_device = &iio_trigger_validate_own_device, .set_trigger_state = &max1027_set_trigger_state, }; static const struct iio_info max1027_info = { - .driver_module = THIS_MODULE, .read_raw = &max1027_read_raw, .validate_trigger = &max1027_validate_trigger, .debugfs_reg_access = &max1027_debugfs_reg_access, diff --git a/drivers/iio/adc/max11100.c b/drivers/iio/adc/max11100.c index 1180bcc22ff1..af59ab2e650c 100644 --- a/drivers/iio/adc/max11100.c +++ b/drivers/iio/adc/max11100.c @@ -100,7 +100,6 @@ static int max11100_read_raw(struct iio_dev *indio_dev, } static const struct iio_info max11100_info = { - .driver_module = THIS_MODULE, .read_raw = max11100_read_raw, }; diff --git a/drivers/iio/adc/max1118.c b/drivers/iio/adc/max1118.c index 2e9648a078c4..49db9e9ae625 100644 --- a/drivers/iio/adc/max1118.c +++ b/drivers/iio/adc/max1118.c @@ -155,7 +155,6 @@ static int max1118_read_raw(struct iio_dev *indio_dev, static const struct iio_info max1118_info = { .read_raw = max1118_read_raw, - .driver_module = THIS_MODULE, }; static irqreturn_t max1118_trigger_handler(int irq, void *p) diff --git a/drivers/iio/adc/max1363.c b/drivers/iio/adc/max1363.c index 80eada4886b3..7f1848dac9bf 100644 --- a/drivers/iio/adc/max1363.c +++ b/drivers/iio/adc/max1363.c @@ -1029,7 +1029,6 @@ static int max1363_update_scan_mode(struct iio_dev *indio_dev, static const struct iio_info max1238_info = { .read_raw = &max1363_read_raw, - .driver_module = THIS_MODULE, .update_scan_mode = &max1363_update_scan_mode, }; @@ -1040,7 +1039,6 @@ static const struct iio_info max1363_info = { .write_event_config = &max1363_write_event_config, .read_raw = &max1363_read_raw, .update_scan_mode = &max1363_update_scan_mode, - .driver_module = THIS_MODULE, .event_attrs = &max1363_event_attribute_group, }; diff --git a/drivers/iio/adc/max9611.c b/drivers/iio/adc/max9611.c index b1dd17cbce58..0538ff8c4ac1 100644 --- a/drivers/iio/adc/max9611.c +++ b/drivers/iio/adc/max9611.c @@ -460,7 +460,6 @@ static const struct attribute_group max9611_attribute_group = { }; static const struct iio_info indio_info = { - .driver_module = THIS_MODULE, .read_raw = max9611_read_raw, .attrs = &max9611_attribute_group, }; @@ -573,7 +572,6 @@ static int max9611_probe(struct i2c_client *client, static struct i2c_driver max9611_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = max9611_of_table, }, .probe = max9611_probe, diff --git a/drivers/iio/adc/mcp320x.c b/drivers/iio/adc/mcp320x.c index 071dd23a33d9..a04856d8afdb 100644 --- a/drivers/iio/adc/mcp320x.c +++ b/drivers/iio/adc/mcp320x.c @@ -19,6 +19,11 @@ * ------------ * 13 bit converter * MCP3301 + * ------------ + * 22 bit converter + * MCP3550 + * MCP3551 + * MCP3553 * * Datasheet can be found here: * http://ww1.microchip.com/downloads/en/DeviceDoc/21293C.pdf mcp3001 @@ -28,6 +33,7 @@ * http://ww1.microchip.com/downloads/en/DeviceDoc/21034D.pdf mcp3202 * http://ww1.microchip.com/downloads/en/DeviceDoc/21298c.pdf mcp3204/08 * http://ww1.microchip.com/downloads/en/DeviceDoc/21700E.pdf mcp3301 + * http://ww1.microchip.com/downloads/en/DeviceDoc/21950D.pdf mcp3550/1/3 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -51,25 +57,45 @@ enum { mcp3204, mcp3208, mcp3301, + mcp3550_50, + mcp3550_60, + mcp3551, + mcp3553, }; struct mcp320x_chip_info { const struct iio_chan_spec *channels; unsigned int num_channels; unsigned int resolution; + unsigned int conv_time; /* usec */ }; +/** + * struct mcp320x - Microchip SPI ADC instance + * @spi: SPI slave (parent of the IIO device) + * @msg: SPI message to select a channel and receive a value from the ADC + * @transfer: SPI transfers used by @msg + * @start_conv_msg: SPI message to start a conversion by briefly asserting CS + * @start_conv_transfer: SPI transfer used by @start_conv_msg + * @reg: regulator generating Vref + * @lock: protects read sequences + * @chip_info: ADC properties + * @tx_buf: buffer for @transfer[0] (not used on single-channel converters) + * @rx_buf: buffer for @transfer[1] + */ struct mcp320x { struct spi_device *spi; struct spi_message msg; struct spi_transfer transfer[2]; + struct spi_message start_conv_msg; + struct spi_transfer start_conv_transfer; struct regulator *reg; struct mutex lock; const struct mcp320x_chip_info *chip_info; u8 tx_buf ____cacheline_aligned; - u8 rx_buf[2]; + u8 rx_buf[4]; }; static int mcp320x_channel_to_tx_data(int device_index, @@ -78,10 +104,6 @@ static int mcp320x_channel_to_tx_data(int device_index, int start_bit = 1; switch (device_index) { - case mcp3001: - case mcp3201: - case mcp3301: - return 0; case mcp3002: case mcp3202: return ((start_bit << 4) | (!differential << 3) | @@ -102,21 +124,24 @@ static int mcp320x_adc_conversion(struct mcp320x *adc, u8 channel, { int ret; - adc->rx_buf[0] = 0; - adc->rx_buf[1] = 0; - adc->tx_buf = mcp320x_channel_to_tx_data(device_index, - channel, differential); - - if (device_index != mcp3001 && device_index != mcp3201 && device_index != mcp3301) { - ret = spi_sync(adc->spi, &adc->msg); - if (ret < 0) - return ret; - } else { - ret = spi_read(adc->spi, &adc->rx_buf, sizeof(adc->rx_buf)); + if (adc->chip_info->conv_time) { + ret = spi_sync(adc->spi, &adc->start_conv_msg); if (ret < 0) return ret; + + usleep_range(adc->chip_info->conv_time, + adc->chip_info->conv_time + 100); } + memset(&adc->rx_buf, 0, sizeof(adc->rx_buf)); + if (adc->chip_info->num_channels > 1) + adc->tx_buf = mcp320x_channel_to_tx_data(device_index, channel, + differential); + + ret = spi_sync(adc->spi, &adc->msg); + if (ret < 0) + return ret; + switch (device_index) { case mcp3001: *val = (adc->rx_buf[0] << 5 | adc->rx_buf[1] >> 3); @@ -138,6 +163,31 @@ static int mcp320x_adc_conversion(struct mcp320x *adc, u8 channel, *val = sign_extend32((adc->rx_buf[0] & 0x1f) << 8 | adc->rx_buf[1], 12); return 0; + case mcp3550_50: + case mcp3550_60: + case mcp3551: + case mcp3553: { + u32 raw = be32_to_cpup((u32 *)adc->rx_buf); + + if (!(adc->spi->mode & SPI_CPOL)) + raw <<= 1; /* strip Data Ready bit in SPI mode 0,0 */ + + /* + * If the input is within -vref and vref, bit 21 is the sign. + * Up to 12% overrange or underrange are allowed, in which case + * bit 23 is the sign and bit 0 to 21 is the value. + */ + raw >>= 8; + if (raw & BIT(22) && raw & BIT(23)) + return -EIO; /* cannot have overrange AND underrange */ + else if (raw & BIT(22)) + raw &= ~BIT(22); /* overrange */ + else if (raw & BIT(23) || raw & BIT(21)) + raw |= GENMASK(31, 22); /* underrange or negative */ + + *val = (s32)raw; + return 0; + } default: return -EINVAL; } @@ -248,7 +298,6 @@ static const struct iio_chan_spec mcp3208_channels[] = { static const struct iio_info mcp320x_info = { .read_raw = mcp320x_read_raw, - .driver_module = THIS_MODULE, }; static const struct mcp320x_chip_info mcp320x_chip_infos[] = { @@ -297,6 +346,31 @@ static const struct mcp320x_chip_info mcp320x_chip_infos[] = { .num_channels = ARRAY_SIZE(mcp3201_channels), .resolution = 13 }, + [mcp3550_50] = { + .channels = mcp3201_channels, + .num_channels = ARRAY_SIZE(mcp3201_channels), + .resolution = 21, + /* 2% max deviation + 144 clock periods to exit shutdown */ + .conv_time = 80000 * 1.02 + 144000 / 102.4, + }, + [mcp3550_60] = { + .channels = mcp3201_channels, + .num_channels = ARRAY_SIZE(mcp3201_channels), + .resolution = 21, + .conv_time = 66670 * 1.02 + 144000 / 122.88, + }, + [mcp3551] = { + .channels = mcp3201_channels, + .num_channels = ARRAY_SIZE(mcp3201_channels), + .resolution = 21, + .conv_time = 73100 * 1.02 + 144000 / 112.64, + }, + [mcp3553] = { + .channels = mcp3201_channels, + .num_channels = ARRAY_SIZE(mcp3201_channels), + .resolution = 21, + .conv_time = 16670 * 1.02 + 144000 / 122.88, + }, }; static int mcp320x_probe(struct spi_device *spi) @@ -304,7 +378,7 @@ static int mcp320x_probe(struct spi_device *spi) struct iio_dev *indio_dev; struct mcp320x *adc; const struct mcp320x_chip_info *chip_info; - int ret; + int ret, device_index; indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc)); if (!indio_dev) @@ -320,7 +394,8 @@ static int mcp320x_probe(struct spi_device *spi) indio_dev->info = &mcp320x_info; spi_set_drvdata(spi, indio_dev); - chip_info = &mcp320x_chip_infos[spi_get_device_id(spi)->driver_data]; + device_index = spi_get_device_id(spi)->driver_data; + chip_info = &mcp320x_chip_infos[device_index]; indio_dev->channels = chip_info->channels; indio_dev->num_channels = chip_info->num_channels; @@ -329,10 +404,41 @@ static int mcp320x_probe(struct spi_device *spi) adc->transfer[0].tx_buf = &adc->tx_buf; adc->transfer[0].len = sizeof(adc->tx_buf); adc->transfer[1].rx_buf = adc->rx_buf; - adc->transfer[1].len = sizeof(adc->rx_buf); + adc->transfer[1].len = DIV_ROUND_UP(chip_info->resolution, 8); + + if (chip_info->num_channels == 1) + /* single-channel converters are rx only (no MOSI pin) */ + spi_message_init_with_transfers(&adc->msg, + &adc->transfer[1], 1); + else + spi_message_init_with_transfers(&adc->msg, adc->transfer, + ARRAY_SIZE(adc->transfer)); - spi_message_init_with_transfers(&adc->msg, adc->transfer, - ARRAY_SIZE(adc->transfer)); + switch (device_index) { + case mcp3550_50: + case mcp3550_60: + case mcp3551: + case mcp3553: + /* rx len increases from 24 to 25 bit in SPI mode 0,0 */ + if (!(spi->mode & SPI_CPOL)) + adc->transfer[1].len++; + + /* conversions are started by asserting CS pin for 8 usec */ + adc->start_conv_transfer.delay_usecs = 8; + spi_message_init_with_transfers(&adc->start_conv_msg, + &adc->start_conv_transfer, 1); + + /* + * If CS was previously kept low (continuous conversion mode) + * and then changed to high, the chip is in shutdown. + * Sometimes it fails to wake from shutdown and clocks out + * only 0xffffff. The magic sequence of performing two + * conversions without delay between them resets the chip + * and ensures all subsequent conversions succeed. + */ + mcp320x_adc_conversion(adc, 0, 1, device_index, &ret); + mcp320x_adc_conversion(adc, 0, 1, device_index, &ret); + } adc->reg = devm_regulator_get(&spi->dev, "vref"); if (IS_ERR(adc->reg)) @@ -370,62 +476,29 @@ static int mcp320x_remove(struct spi_device *spi) #if defined(CONFIG_OF) static const struct of_device_id mcp320x_dt_ids[] = { /* NOTE: The use of compatibles with no vendor prefix is deprecated. */ - { - .compatible = "mcp3001", - .data = &mcp320x_chip_infos[mcp3001], - }, { - .compatible = "mcp3002", - .data = &mcp320x_chip_infos[mcp3002], - }, { - .compatible = "mcp3004", - .data = &mcp320x_chip_infos[mcp3004], - }, { - .compatible = "mcp3008", - .data = &mcp320x_chip_infos[mcp3008], - }, { - .compatible = "mcp3201", - .data = &mcp320x_chip_infos[mcp3201], - }, { - .compatible = "mcp3202", - .data = &mcp320x_chip_infos[mcp3202], - }, { - .compatible = "mcp3204", - .data = &mcp320x_chip_infos[mcp3204], - }, { - .compatible = "mcp3208", - .data = &mcp320x_chip_infos[mcp3208], - }, { - .compatible = "mcp3301", - .data = &mcp320x_chip_infos[mcp3301], - }, { - .compatible = "microchip,mcp3001", - .data = &mcp320x_chip_infos[mcp3001], - }, { - .compatible = "microchip,mcp3002", - .data = &mcp320x_chip_infos[mcp3002], - }, { - .compatible = "microchip,mcp3004", - .data = &mcp320x_chip_infos[mcp3004], - }, { - .compatible = "microchip,mcp3008", - .data = &mcp320x_chip_infos[mcp3008], - }, { - .compatible = "microchip,mcp3201", - .data = &mcp320x_chip_infos[mcp3201], - }, { - .compatible = "microchip,mcp3202", - .data = &mcp320x_chip_infos[mcp3202], - }, { - .compatible = "microchip,mcp3204", - .data = &mcp320x_chip_infos[mcp3204], - }, { - .compatible = "microchip,mcp3208", - .data = &mcp320x_chip_infos[mcp3208], - }, { - .compatible = "microchip,mcp3301", - .data = &mcp320x_chip_infos[mcp3301], - }, { - } + { .compatible = "mcp3001" }, + { .compatible = "mcp3002" }, + { .compatible = "mcp3004" }, + { .compatible = "mcp3008" }, + { .compatible = "mcp3201" }, + { .compatible = "mcp3202" }, + { .compatible = "mcp3204" }, + { .compatible = "mcp3208" }, + { .compatible = "mcp3301" }, + { .compatible = "microchip,mcp3001" }, + { .compatible = "microchip,mcp3002" }, + { .compatible = "microchip,mcp3004" }, + { .compatible = "microchip,mcp3008" }, + { .compatible = "microchip,mcp3201" }, + { .compatible = "microchip,mcp3202" }, + { .compatible = "microchip,mcp3204" }, + { .compatible = "microchip,mcp3208" }, + { .compatible = "microchip,mcp3301" }, + { .compatible = "microchip,mcp3550-50" }, + { .compatible = "microchip,mcp3550-60" }, + { .compatible = "microchip,mcp3551" }, + { .compatible = "microchip,mcp3553" }, + { } }; MODULE_DEVICE_TABLE(of, mcp320x_dt_ids); #endif @@ -440,6 +513,10 @@ static const struct spi_device_id mcp320x_id[] = { { "mcp3204", mcp3204 }, { "mcp3208", mcp3208 }, { "mcp3301", mcp3301 }, + { "mcp3550-50", mcp3550_50 }, + { "mcp3550-60", mcp3550_60 }, + { "mcp3551", mcp3551 }, + { "mcp3553", mcp3553 }, { } }; MODULE_DEVICE_TABLE(spi, mcp320x_id); @@ -456,5 +533,5 @@ static struct spi_driver mcp320x_driver = { module_spi_driver(mcp320x_driver); MODULE_AUTHOR("Oskar Andero <oskar.andero@gmail.com>"); -MODULE_DESCRIPTION("Microchip Technology MCP3x01/02/04/08"); +MODULE_DESCRIPTION("Microchip Technology MCP3x01/02/04/08 and MCP3550/1/3"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/adc/mcp3422.c b/drivers/iio/adc/mcp3422.c index 63de705086ed..819f26011500 100644 --- a/drivers/iio/adc/mcp3422.c +++ b/drivers/iio/adc/mcp3422.c @@ -327,7 +327,6 @@ static const struct iio_info mcp3422_info = { .write_raw = mcp3422_write_raw, .write_raw_get_fmt = mcp3422_write_raw_get_fmt, .attrs = &mcp3422_attribute_group, - .driver_module = THIS_MODULE, }; static int mcp3422_probe(struct i2c_client *client, diff --git a/drivers/iio/adc/men_z188_adc.c b/drivers/iio/adc/men_z188_adc.c index 8f3606de4eaf..c80261748d8f 100644 --- a/drivers/iio/adc/men_z188_adc.c +++ b/drivers/iio/adc/men_z188_adc.c @@ -80,7 +80,6 @@ static int z188_iio_read_raw(struct iio_dev *iio_dev, static const struct iio_info z188_adc_info = { .read_raw = &z188_iio_read_raw, - .driver_module = THIS_MODULE, }; static void men_z188_config_channels(void __iomem *addr) diff --git a/drivers/iio/adc/meson_saradc.c b/drivers/iio/adc/meson_saradc.c index 2e8dbb89c8c9..9c6932ffc0af 100644 --- a/drivers/iio/adc/meson_saradc.c +++ b/drivers/iio/adc/meson_saradc.c @@ -840,7 +840,6 @@ out: static const struct iio_info meson_sar_adc_iio_info = { .read_raw = meson_sar_adc_iio_info_read_raw, - .driver_module = THIS_MODULE, }; static const struct meson_sar_adc_data meson_sar_adc_meson8_data = { diff --git a/drivers/iio/adc/mt6577_auxadc.c b/drivers/iio/adc/mt6577_auxadc.c index 414cf44bf19d..95d76abb64ec 100644 --- a/drivers/iio/adc/mt6577_auxadc.c +++ b/drivers/iio/adc/mt6577_auxadc.c @@ -180,7 +180,6 @@ static int mt6577_auxadc_read_raw(struct iio_dev *indio_dev, } static const struct iio_info mt6577_auxadc_info = { - .driver_module = THIS_MODULE, .read_raw = &mt6577_auxadc_read_raw, }; @@ -306,6 +305,7 @@ static SIMPLE_DEV_PM_OPS(mt6577_auxadc_pm_ops, static const struct of_device_id mt6577_auxadc_of_match[] = { { .compatible = "mediatek,mt2701-auxadc", }, + { .compatible = "mediatek,mt2712-auxadc", }, { .compatible = "mediatek,mt7622-auxadc", }, { .compatible = "mediatek,mt8173-auxadc", }, { } diff --git a/drivers/iio/adc/mxs-lradc-adc.c b/drivers/iio/adc/mxs-lradc-adc.c index d32b34638c2f..c627513d9f0f 100644 --- a/drivers/iio/adc/mxs-lradc-adc.c +++ b/drivers/iio/adc/mxs-lradc-adc.c @@ -382,7 +382,6 @@ static const struct attribute_group mxs_lradc_adc_attribute_group = { }; static const struct iio_info mxs_lradc_adc_iio_info = { - .driver_module = THIS_MODULE, .read_raw = mxs_lradc_adc_read_raw, .write_raw = mxs_lradc_adc_write_raw, .write_raw_get_fmt = mxs_lradc_adc_write_raw_get_fmt, @@ -455,7 +454,6 @@ static int mxs_lradc_adc_configure_trigger(struct iio_trigger *trig, bool state) } static const struct iio_trigger_ops mxs_lradc_adc_trigger_ops = { - .owner = THIS_MODULE, .set_trigger_state = &mxs_lradc_adc_configure_trigger, }; diff --git a/drivers/iio/adc/nau7802.c b/drivers/iio/adc/nau7802.c index 08f446695f97..8997e74a8847 100644 --- a/drivers/iio/adc/nau7802.c +++ b/drivers/iio/adc/nau7802.c @@ -402,7 +402,6 @@ static int nau7802_write_raw_get_fmt(struct iio_dev *indio_dev, } static const struct iio_info nau7802_info = { - .driver_module = THIS_MODULE, .read_raw = &nau7802_read_raw, .write_raw = &nau7802_write_raw, .write_raw_get_fmt = nau7802_write_raw_get_fmt, diff --git a/drivers/iio/adc/palmas_gpadc.c b/drivers/iio/adc/palmas_gpadc.c index 7d61b566e148..69b9affeef1e 100644 --- a/drivers/iio/adc/palmas_gpadc.c +++ b/drivers/iio/adc/palmas_gpadc.c @@ -430,7 +430,6 @@ out: static const struct iio_info palmas_gpadc_iio_info = { .read_raw = palmas_gpadc_read_raw, - .driver_module = THIS_MODULE, }; #define PALMAS_ADC_CHAN_IIO(chan, _type, chan_info) \ diff --git a/drivers/iio/adc/qcom-pm8xxx-xoadc.c b/drivers/iio/adc/qcom-pm8xxx-xoadc.c index cea8f1fb444a..b093ecddf1a8 100644 --- a/drivers/iio/adc/qcom-pm8xxx-xoadc.c +++ b/drivers/iio/adc/qcom-pm8xxx-xoadc.c @@ -728,7 +728,6 @@ static int pm8xxx_of_xlate(struct iio_dev *indio_dev, } static const struct iio_info pm8xxx_xoadc_info = { - .driver_module = THIS_MODULE, .of_xlate = pm8xxx_of_xlate, .read_raw = pm8xxx_read_raw, }; diff --git a/drivers/iio/adc/qcom-spmi-iadc.c b/drivers/iio/adc/qcom-spmi-iadc.c index fabd24edc2a1..3f062cd61aba 100644 --- a/drivers/iio/adc/qcom-spmi-iadc.c +++ b/drivers/iio/adc/qcom-spmi-iadc.c @@ -356,7 +356,6 @@ static int iadc_read_raw(struct iio_dev *indio_dev, static const struct iio_info iadc_info = { .read_raw = iadc_read_raw, - .driver_module = THIS_MODULE, }; static irqreturn_t iadc_isr(int irq, void *dev_id) diff --git a/drivers/iio/adc/qcom-spmi-vadc.c b/drivers/iio/adc/qcom-spmi-vadc.c index 9e600bfd1765..3680e0d47412 100644 --- a/drivers/iio/adc/qcom-spmi-vadc.c +++ b/drivers/iio/adc/qcom-spmi-vadc.c @@ -506,7 +506,6 @@ static int vadc_of_xlate(struct iio_dev *indio_dev, static const struct iio_info vadc_info = { .read_raw = vadc_read_raw, .of_xlate = vadc_of_xlate, - .driver_module = THIS_MODULE, }; struct vadc_channels { diff --git a/drivers/iio/adc/rcar-gyroadc.c b/drivers/iio/adc/rcar-gyroadc.c index 27a318164619..dcb50172186f 100644 --- a/drivers/iio/adc/rcar-gyroadc.c +++ b/drivers/iio/adc/rcar-gyroadc.c @@ -277,7 +277,6 @@ static int rcar_gyroadc_reg_access(struct iio_dev *indio_dev, } static const struct iio_info rcar_gyroadc_iio_info = { - .driver_module = THIS_MODULE, .read_raw = rcar_gyroadc_read_raw, .debugfs_reg_access = rcar_gyroadc_reg_access, }; @@ -349,7 +348,7 @@ static int rcar_gyroadc_parse_subdevs(struct iio_dev *indio_dev) continue; } - childmode = (unsigned int)of_id->data; + childmode = (uintptr_t)of_id->data; switch (childmode) { case RCAR_GYROADC_MODE_SELECT_1_MB88101A: sample_width = 12; @@ -488,8 +487,6 @@ err: static int rcar_gyroadc_probe(struct platform_device *pdev) { - const struct of_device_id *of_id = - of_match_device(rcar_gyroadc_match, &pdev->dev); struct device *dev = &pdev->dev; struct rcar_gyroadc *priv; struct iio_dev *indio_dev; @@ -526,7 +523,8 @@ static int rcar_gyroadc_probe(struct platform_device *pdev) if (ret) return ret; - priv->model = (enum rcar_gyroadc_model)of_id->data; + priv->model = (enum rcar_gyroadc_model) + of_device_get_match_data(&pdev->dev); platform_set_drvdata(pdev, indio_dev); diff --git a/drivers/iio/adc/rockchip_saradc.c b/drivers/iio/adc/rockchip_saradc.c index 5f612d694b33..1f98566d5b3c 100644 --- a/drivers/iio/adc/rockchip_saradc.c +++ b/drivers/iio/adc/rockchip_saradc.c @@ -125,7 +125,6 @@ static irqreturn_t rockchip_saradc_isr(int irq, void *dev_id) static const struct iio_info rockchip_saradc_iio_info = { .read_raw = rockchip_saradc_read_raw, - .driver_module = THIS_MODULE, }; #define ADC_CHANNEL(_index, _id) { \ diff --git a/drivers/iio/adc/spear_adc.c b/drivers/iio/adc/spear_adc.c index 5dd61f6a57b9..b1da2c46107c 100644 --- a/drivers/iio/adc/spear_adc.c +++ b/drivers/iio/adc/spear_adc.c @@ -254,7 +254,6 @@ static int spear_adc_configure(struct spear_adc_state *st) static const struct iio_info spear_adc_info = { .read_raw = &spear_adc_read_raw, .write_raw = &spear_adc_write_raw, - .driver_module = THIS_MODULE, }; static int spear_adc_probe(struct platform_device *pdev) diff --git a/drivers/iio/adc/stm32-adc-core.c b/drivers/iio/adc/stm32-adc-core.c index 804198eb0eef..6aefef99f935 100644 --- a/drivers/iio/adc/stm32-adc-core.c +++ b/drivers/iio/adc/stm32-adc-core.c @@ -139,6 +139,11 @@ static int stm32f4_adc_clk_sel(struct platform_device *pdev, } rate = clk_get_rate(priv->aclk); + if (!rate) { + dev_err(&pdev->dev, "Invalid clock rate: 0\n"); + return -EINVAL; + } + for (i = 0; i < ARRAY_SIZE(stm32f4_pclk_div); i++) { if ((rate / stm32f4_pclk_div[i]) <= STM32F4_ADC_MAX_CLK_RATE) break; @@ -216,6 +221,10 @@ static int stm32h7_adc_clk_sel(struct platform_device *pdev, * From spec: PLL output musn't exceed max rate */ rate = clk_get_rate(priv->aclk); + if (!rate) { + dev_err(&pdev->dev, "Invalid adc clock rate: 0\n"); + return -EINVAL; + } for (i = 0; i < ARRAY_SIZE(stm32h7_adc_ckmodes_spec); i++) { ckmode = stm32h7_adc_ckmodes_spec[i].ckmode; @@ -232,6 +241,10 @@ static int stm32h7_adc_clk_sel(struct platform_device *pdev, /* Synchronous clock modes (e.g. ckmode is 1, 2 or 3) */ rate = clk_get_rate(priv->bclk); + if (!rate) { + dev_err(&pdev->dev, "Invalid bus clock rate: 0\n"); + return -EINVAL; + } for (i = 0; i < ARRAY_SIZE(stm32h7_adc_ckmodes_spec); i++) { ckmode = stm32h7_adc_ckmodes_spec[i].ckmode; diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c index 4df32cf1650e..c9d96f935dba 100644 --- a/drivers/iio/adc/stm32-adc.c +++ b/drivers/iio/adc/stm32-adc.c @@ -531,6 +531,7 @@ static struct stm32_adc_trig_info stm32h7_adc_trigs[] = { { TIM2_TRGO, STM32_EXT11 }, { TIM4_TRGO, STM32_EXT12 }, { TIM6_TRGO, STM32_EXT13 }, + { TIM15_TRGO, STM32_EXT14 }, { TIM3_CH4, STM32_EXT15 }, { LPTIM1_OUT, STM32_EXT18 }, { LPTIM2_OUT, STM32_EXT19 }, @@ -1385,7 +1386,6 @@ static const struct iio_info stm32_adc_iio_info = { .update_scan_mode = stm32_adc_update_scan_mode, .debugfs_reg_access = stm32_adc_debugfs_reg_access, .of_xlate = stm32_adc_of_xlate, - .driver_module = THIS_MODULE, }; static unsigned int stm32_adc_dma_residue(struct stm32_adc *adc) diff --git a/drivers/iio/adc/stx104.c b/drivers/iio/adc/stx104.c index 2da741d27540..17b021f33180 100644 --- a/drivers/iio/adc/stx104.c +++ b/drivers/iio/adc/stx104.c @@ -172,7 +172,6 @@ static int stx104_write_raw(struct iio_dev *indio_dev, } static const struct iio_info stx104_info = { - .driver_module = THIS_MODULE, .read_raw = stx104_read_raw, .write_raw = stx104_write_raw }; diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c index 137f577d9432..04d7147e0110 100644 --- a/drivers/iio/adc/sun4i-gpadc-iio.c +++ b/drivers/iio/adc/sun4i-gpadc-iio.c @@ -352,7 +352,6 @@ static int sun4i_gpadc_read_raw(struct iio_dev *indio_dev, static const struct iio_info sun4i_gpadc_iio_info = { .read_raw = sun4i_gpadc_read_raw, - .driver_module = THIS_MODULE, }; static irqreturn_t sun4i_gpadc_temp_data_irq_handler(int irq, void *dev_id) @@ -502,17 +501,15 @@ static int sun4i_gpadc_probe_dt(struct platform_device *pdev, struct iio_dev *indio_dev) { struct sun4i_gpadc_iio *info = iio_priv(indio_dev); - const struct of_device_id *of_dev; struct resource *mem; void __iomem *base; int ret; - of_dev = of_match_device(sun4i_gpadc_of_id, &pdev->dev); - if (!of_dev) + info->data = of_device_get_match_data(&pdev->dev); + if (!info->data) return -ENODEV; info->no_irq = true; - info->data = (struct gpadc_data *)of_dev->data; indio_dev->num_channels = ARRAY_SIZE(sun8i_a33_gpadc_channels); indio_dev->channels = sun8i_a33_gpadc_channels; @@ -529,17 +526,10 @@ static int sun4i_gpadc_probe_dt(struct platform_device *pdev, return ret; } - if (!IS_ENABLED(CONFIG_THERMAL_OF)) - return 0; + if (IS_ENABLED(CONFIG_THERMAL_OF)) + info->sensor_device = &pdev->dev; - info->sensor_device = &pdev->dev; - info->tzd = thermal_zone_of_sensor_register(info->sensor_device, 0, - info, &sun4i_ts_tz_ops); - if (IS_ERR(info->tzd)) - dev_err(&pdev->dev, "could not register thermal sensor: %ld\n", - PTR_ERR(info->tzd)); - - return PTR_ERR_OR_ZERO(info->tzd); + return 0; } static int sun4i_gpadc_probe_mfd(struct platform_device *pdev, @@ -586,15 +576,6 @@ static int sun4i_gpadc_probe_mfd(struct platform_device *pdev, * return the temperature. */ info->sensor_device = pdev->dev.parent; - info->tzd = thermal_zone_of_sensor_register(info->sensor_device, - 0, info, - &sun4i_ts_tz_ops); - if (IS_ERR(info->tzd)) { - dev_err(&pdev->dev, - "could not register thermal sensor: %ld\n", - PTR_ERR(info->tzd)); - return PTR_ERR(info->tzd); - } } else { indio_dev->num_channels = ARRAY_SIZE(sun4i_gpadc_channels_no_temp); @@ -664,6 +645,22 @@ static int sun4i_gpadc_probe(struct platform_device *pdev) pm_runtime_set_suspended(&pdev->dev); pm_runtime_enable(&pdev->dev); + if (IS_ENABLED(CONFIG_THERMAL_OF)) { + info->tzd = thermal_zone_of_sensor_register(info->sensor_device, + 0, info, + &sun4i_ts_tz_ops); + /* + * Do not fail driver probing when failing to register in + * thermal because no thermal DT node is found. + */ + if (IS_ERR(info->tzd) && PTR_ERR(info->tzd) != -ENODEV) { + dev_err(&pdev->dev, + "could not register thermal sensor: %ld\n", + PTR_ERR(info->tzd)); + return PTR_ERR(info->tzd); + } + } + ret = devm_iio_device_register(&pdev->dev, indio_dev); if (ret < 0) { dev_err(&pdev->dev, "could not register the device\n"); diff --git a/drivers/iio/adc/ti-adc081c.c b/drivers/iio/adc/ti-adc081c.c index 319172cf7da8..405e3779c0c5 100644 --- a/drivers/iio/adc/ti-adc081c.c +++ b/drivers/iio/adc/ti-adc081c.c @@ -124,7 +124,6 @@ static struct adcxx1c_model adcxx1c_models[] = { static const struct iio_info adc081c_info = { .read_raw = adc081c_read_raw, - .driver_module = THIS_MODULE, }; static irqreturn_t adc081c_trigger_handler(int irq, void *p) diff --git a/drivers/iio/adc/ti-adc0832.c b/drivers/iio/adc/ti-adc0832.c index e952e94a14af..188dae705bf7 100644 --- a/drivers/iio/adc/ti-adc0832.c +++ b/drivers/iio/adc/ti-adc0832.c @@ -195,7 +195,6 @@ static int adc0832_read_raw(struct iio_dev *iio, static const struct iio_info adc0832_info = { .read_raw = adc0832_read_raw, - .driver_module = THIS_MODULE, }; static irqreturn_t adc0832_trigger_handler(int irq, void *p) diff --git a/drivers/iio/adc/ti-adc084s021.c b/drivers/iio/adc/ti-adc084s021.c index a355121c11a4..25504640e126 100644 --- a/drivers/iio/adc/ti-adc084s021.c +++ b/drivers/iio/adc/ti-adc084s021.c @@ -186,7 +186,6 @@ static int adc084s021_buffer_postdisable(struct iio_dev *indio_dev) static const struct iio_info adc084s021_info = { .read_raw = adc084s021_read_raw, - .driver_module = THIS_MODULE, }; static const struct iio_buffer_setup_ops adc084s021_buffer_setup_ops = { diff --git a/drivers/iio/adc/ti-adc108s102.c b/drivers/iio/adc/ti-adc108s102.c index de4e5ac98c6e..841203edaac5 100644 --- a/drivers/iio/adc/ti-adc108s102.c +++ b/drivers/iio/adc/ti-adc108s102.c @@ -220,7 +220,6 @@ static int adc108s102_read_raw(struct iio_dev *indio_dev, static const struct iio_info adc108s102_info = { .read_raw = &adc108s102_read_raw, .update_scan_mode = &adc108s102_update_scan_mode, - .driver_module = THIS_MODULE, }; static int adc108s102_probe(struct spi_device *spi) diff --git a/drivers/iio/adc/ti-adc12138.c b/drivers/iio/adc/ti-adc12138.c index 072f03bfe6a0..703d68ae96b7 100644 --- a/drivers/iio/adc/ti-adc12138.c +++ b/drivers/iio/adc/ti-adc12138.c @@ -164,7 +164,7 @@ static int __adc12138_start_conv(struct adc12138 *adc, void *data, int len) { - const u8 ch_to_mux[] = { 0, 4, 1, 5, 2, 6, 3, 7 }; + static const u8 ch_to_mux[] = { 0, 4, 1, 5, 2, 6, 3, 7 }; u8 mode = (ch_to_mux[channel->channel] << 4) | (channel->differential ? 0 : 0x80); @@ -277,7 +277,6 @@ static int adc12138_read_raw(struct iio_dev *iio, static const struct iio_info adc12138_info = { .read_raw = adc12138_read_raw, - .driver_module = THIS_MODULE, }; static int adc12138_init(struct adc12138 *adc) diff --git a/drivers/iio/adc/ti-adc128s052.c b/drivers/iio/adc/ti-adc128s052.c index 89dfbd31be5c..7cf39b3e2416 100644 --- a/drivers/iio/adc/ti-adc128s052.c +++ b/drivers/iio/adc/ti-adc128s052.c @@ -130,7 +130,6 @@ static const struct adc128_configuration adc128_config[] = { static const struct iio_info adc128_info = { .read_raw = adc128_read_raw, - .driver_module = THIS_MODULE, }; static int adc128_probe(struct spi_device *spi) diff --git a/drivers/iio/adc/ti-adc161s626.c b/drivers/iio/adc/ti-adc161s626.c index 4836a0d7aef5..10fa7677ac4b 100644 --- a/drivers/iio/adc/ti-adc161s626.c +++ b/drivers/iio/adc/ti-adc161s626.c @@ -173,7 +173,6 @@ static int ti_adc_read_raw(struct iio_dev *indio_dev, } static const struct iio_info ti_adc_info = { - .driver_module = THIS_MODULE, .read_raw = ti_adc_read_raw, }; diff --git a/drivers/iio/adc/ti-ads1015.c b/drivers/iio/adc/ti-ads1015.c index e0dc20488335..6a114dcb4a3a 100644 --- a/drivers/iio/adc/ti-ads1015.c +++ b/drivers/iio/adc/ti-ads1015.c @@ -332,7 +332,7 @@ static int ads1015_set_power_state(struct ads1015_data *data, bool on) static int ads1015_get_adc_result(struct ads1015_data *data, int chan, int *val) { - int ret, pga, dr, conv_time; + int ret, pga, dr, dr_old, conv_time; unsigned int old, mask, cfg; if (chan < 0 || chan >= ADS1015_CHANNELS) @@ -358,17 +358,17 @@ int ads1015_get_adc_result(struct ads1015_data *data, int chan, int *val) } cfg = (old & ~mask) | (cfg & mask); - - ret = regmap_write(data->regmap, ADS1015_CFG_REG, cfg); - if (ret) - return ret; - - if (old != cfg || data->conv_invalid) { - int dr_old = (old & ADS1015_CFG_DR_MASK) >> - ADS1015_CFG_DR_SHIFT; - + if (old != cfg) { + ret = regmap_write(data->regmap, ADS1015_CFG_REG, cfg); + if (ret) + return ret; + data->conv_invalid = true; + } + if (data->conv_invalid) { + dr_old = (old & ADS1015_CFG_DR_MASK) >> ADS1015_CFG_DR_SHIFT; conv_time = DIV_ROUND_UP(USEC_PER_SEC, data->data_rate[dr_old]); conv_time += DIV_ROUND_UP(USEC_PER_SEC, data->data_rate[dr]); + conv_time += conv_time / 10; /* 10% internal clock inaccuracy */ usleep_range(conv_time, conv_time + 1); data->conv_invalid = false; } @@ -821,7 +821,6 @@ static const struct attribute_group ads1115_attribute_group = { }; static const struct iio_info ads1015_info = { - .driver_module = THIS_MODULE, .read_raw = ads1015_read_raw, .write_raw = ads1015_write_raw, .read_event_value = ads1015_read_event, @@ -832,7 +831,6 @@ static const struct iio_info ads1015_info = { }; static const struct iio_info ads1115_info = { - .driver_module = THIS_MODULE, .read_raw = ads1015_read_raw, .write_raw = ads1015_write_raw, .read_event_value = ads1015_read_event, diff --git a/drivers/iio/adc/ti-ads7950.c b/drivers/iio/adc/ti-ads7950.c index a376190914ad..0225c1b333ab 100644 --- a/drivers/iio/adc/ti-ads7950.c +++ b/drivers/iio/adc/ti-ads7950.c @@ -372,7 +372,6 @@ static int ti_ads7950_read_raw(struct iio_dev *indio_dev, static const struct iio_info ti_ads7950_info = { .read_raw = &ti_ads7950_read_raw, .update_scan_mode = ti_ads7950_update_scan_mode, - .driver_module = THIS_MODULE, }; static int ti_ads7950_probe(struct spi_device *spi) diff --git a/drivers/iio/adc/ti-ads8688.c b/drivers/iio/adc/ti-ads8688.c index 4a163496d9e4..079f133144b0 100644 --- a/drivers/iio/adc/ti-ads8688.c +++ b/drivers/iio/adc/ti-ads8688.c @@ -369,7 +369,6 @@ static const struct iio_info ads8688_info = { .write_raw = &ads8688_write_raw, .write_raw_get_fmt = &ads8688_write_raw_get_fmt, .attrs = &ads8688_attribute_group, - .driver_module = THIS_MODULE, }; static const struct ads8688_chip_info ads8688_chip_info_tbl[] = { @@ -474,7 +473,6 @@ MODULE_DEVICE_TABLE(of, ads8688_of_match); static struct spi_driver ads8688_driver = { .driver = { .name = "ads8688", - .owner = THIS_MODULE, }, .probe = ads8688_probe, .remove = ads8688_remove, diff --git a/drivers/iio/adc/ti-tlc4541.c b/drivers/iio/adc/ti-tlc4541.c index 78d91a069ea4..2290024c89fc 100644 --- a/drivers/iio/adc/ti-tlc4541.c +++ b/drivers/iio/adc/ti-tlc4541.c @@ -157,7 +157,6 @@ static int tlc4541_read_raw(struct iio_dev *indio_dev, static const struct iio_info tlc4541_info = { .read_raw = &tlc4541_read_raw, - .driver_module = THIS_MODULE, }; static int tlc4541_probe(struct spi_device *spi) diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c index 6cbed7eb118a..b3e573cc6f5f 100644 --- a/drivers/iio/adc/ti_am335x_adc.c +++ b/drivers/iio/adc/ti_am335x_adc.c @@ -533,7 +533,6 @@ err_unlock: static const struct iio_info tiadc_info = { .read_raw = &tiadc_read_raw, - .driver_module = THIS_MODULE, }; static int tiadc_request_dma(struct platform_device *pdev, diff --git a/drivers/iio/adc/twl4030-madc.c b/drivers/iio/adc/twl4030-madc.c index e3cfb91bffc6..8c019bb6625f 100644 --- a/drivers/iio/adc/twl4030-madc.c +++ b/drivers/iio/adc/twl4030-madc.c @@ -212,7 +212,6 @@ static int twl4030_madc_read(struct iio_dev *iio_dev, static const struct iio_info twl4030_madc_iio_info = { .read_raw = &twl4030_madc_read, - .driver_module = THIS_MODULE, }; #define TWL4030_ADC_CHANNEL(_channel, _type, _name) { \ diff --git a/drivers/iio/adc/twl6030-gpadc.c b/drivers/iio/adc/twl6030-gpadc.c index bc0e60b9da45..dc83f8f6c3d3 100644 --- a/drivers/iio/adc/twl6030-gpadc.c +++ b/drivers/iio/adc/twl6030-gpadc.c @@ -843,7 +843,6 @@ static const struct iio_chan_spec twl6032_gpadc_iio_channels[] = { static const struct iio_info twl6030_gpadc_iio_info = { .read_raw = &twl6030_gpadc_read_raw, - .driver_module = THIS_MODULE, }; static const struct twl6030_gpadc_platform_data twl6030_pdata = { diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c index c168e0db329a..bbcb7a4d7edf 100644 --- a/drivers/iio/adc/vf610_adc.c +++ b/drivers/iio/adc/vf610_adc.c @@ -799,7 +799,6 @@ static int vf610_adc_reg_access(struct iio_dev *indio_dev, } static const struct iio_info vf610_adc_iio_info = { - .driver_module = THIS_MODULE, .read_raw = &vf610_read_raw, .write_raw = &vf610_write_raw, .debugfs_reg_access = &vf610_adc_reg_access, diff --git a/drivers/iio/adc/viperboard_adc.c b/drivers/iio/adc/viperboard_adc.c index 3be2e35721cc..53eb5a4136fe 100644 --- a/drivers/iio/adc/viperboard_adc.c +++ b/drivers/iio/adc/viperboard_adc.c @@ -107,7 +107,6 @@ error: static const struct iio_info vprbrd_adc_iio_info = { .read_raw = &vprbrd_iio_read_raw, - .driver_module = THIS_MODULE, }; static int vprbrd_adc_probe(struct platform_device *pdev) diff --git a/drivers/iio/adc/xilinx-xadc-core.c b/drivers/iio/adc/xilinx-xadc-core.c index 4a60497a1f19..d4f21d1be6c8 100644 --- a/drivers/iio/adc/xilinx-xadc-core.c +++ b/drivers/iio/adc/xilinx-xadc-core.c @@ -675,7 +675,6 @@ err_out: } static const struct iio_trigger_ops xadc_trigger_ops = { - .owner = THIS_MODULE, .set_trigger_state = &xadc_trigger_set_state, }; @@ -1028,7 +1027,6 @@ static const struct iio_info xadc_info = { .read_event_value = &xadc_read_event_value, .write_event_value = &xadc_write_event_value, .update_scan_mode = &xadc_update_scan_mode, - .driver_module = THIS_MODULE, }; static const struct of_device_id xadc_of_match_table[] = { diff --git a/drivers/iio/amplifiers/ad8366.c b/drivers/iio/amplifiers/ad8366.c index 102c7174da5b..43667866321e 100644 --- a/drivers/iio/amplifiers/ad8366.c +++ b/drivers/iio/amplifiers/ad8366.c @@ -117,7 +117,6 @@ static int ad8366_write_raw(struct iio_dev *indio_dev, static const struct iio_info ad8366_info = { .read_raw = &ad8366_read_raw, .write_raw = &ad8366_write_raw, - .driver_module = THIS_MODULE, }; #define AD8366_CHAN(_channel) { \ diff --git a/drivers/iio/chemical/ams-iaq-core.c b/drivers/iio/chemical/ams-iaq-core.c index c948ad2ee9ad..d9e5950ad24a 100644 --- a/drivers/iio/chemical/ams-iaq-core.c +++ b/drivers/iio/chemical/ams-iaq-core.c @@ -141,7 +141,6 @@ err_out: static const struct iio_info ams_iaqcore_info = { .read_raw = ams_iaqcore_read_raw, - .driver_module = THIS_MODULE, }; static int ams_iaqcore_probe(struct i2c_client *client, diff --git a/drivers/iio/chemical/atlas-ph-sensor.c b/drivers/iio/chemical/atlas-ph-sensor.c index ef761a508630..8c4e05580091 100644 --- a/drivers/iio/chemical/atlas-ph-sensor.c +++ b/drivers/iio/chemical/atlas-ph-sensor.c @@ -344,7 +344,6 @@ static int atlas_buffer_predisable(struct iio_dev *indio_dev) } static const struct iio_trigger_ops atlas_interrupt_trigger_ops = { - .owner = THIS_MODULE, }; static const struct iio_buffer_setup_ops atlas_buffer_setup_ops = { @@ -499,7 +498,6 @@ static int atlas_write_raw(struct iio_dev *indio_dev, } static const struct iio_info atlas_info = { - .driver_module = THIS_MODULE, .read_raw = atlas_read_raw, .write_raw = atlas_write_raw, }; diff --git a/drivers/iio/chemical/ccs811.c b/drivers/iio/chemical/ccs811.c index 840a6cbd5f0f..97bce8345c6a 100644 --- a/drivers/iio/chemical/ccs811.c +++ b/drivers/iio/chemical/ccs811.c @@ -22,6 +22,7 @@ #include <linux/i2c.h> #include <linux/iio/iio.h> #include <linux/iio/buffer.h> +#include <linux/iio/trigger.h> #include <linux/iio/triggered_buffer.h> #include <linux/iio/trigger_consumer.h> #include <linux/module.h> @@ -59,6 +60,8 @@ #define CCS811_MODE_IAQ_60SEC 0x30 #define CCS811_MODE_RAW_DATA 0x40 +#define CCS811_MEAS_MODE_INTERRUPT BIT(3) + #define CCS811_VOLTAGE_MASK 0x3FF struct ccs811_reading { @@ -73,6 +76,8 @@ struct ccs811_data { struct i2c_client *client; struct mutex lock; /* Protect readings */ struct ccs811_reading buffer; + struct iio_trigger *drdy_trig; + bool drdy_trig_on; }; static const struct iio_chan_spec ccs811_channels[] = { @@ -193,10 +198,14 @@ static int ccs811_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; mutex_lock(&data->lock); ret = ccs811_get_measurement(data); if (ret < 0) { mutex_unlock(&data->lock); + iio_device_release_direct_mode(indio_dev); return ret; } @@ -228,6 +237,7 @@ static int ccs811_read_raw(struct iio_dev *indio_dev, ret = -EINVAL; } mutex_unlock(&data->lock); + iio_device_release_direct_mode(indio_dev); return ret; @@ -270,7 +280,31 @@ static int ccs811_read_raw(struct iio_dev *indio_dev, static const struct iio_info ccs811_info = { .read_raw = ccs811_read_raw, - .driver_module = THIS_MODULE, +}; + +static int ccs811_set_trigger_state(struct iio_trigger *trig, + bool state) +{ + struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); + struct ccs811_data *data = iio_priv(indio_dev); + int ret; + + ret = i2c_smbus_read_byte_data(data->client, CCS811_MEAS_MODE); + if (ret < 0) + return ret; + + if (state) + ret |= CCS811_MEAS_MODE_INTERRUPT; + else + ret &= ~CCS811_MEAS_MODE_INTERRUPT; + + data->drdy_trig_on = state; + + return i2c_smbus_write_byte_data(data->client, CCS811_MEAS_MODE, ret); +} + +static const struct iio_trigger_ops ccs811_trigger_ops = { + .set_trigger_state = ccs811_set_trigger_state, }; static irqreturn_t ccs811_trigger_handler(int irq, void *p) @@ -298,6 +332,17 @@ err: return IRQ_HANDLED; } +static irqreturn_t ccs811_data_rdy_trigger_poll(int irq, void *private) +{ + struct iio_dev *indio_dev = private; + struct ccs811_data *data = iio_priv(indio_dev); + + if (data->drdy_trig_on) + iio_trigger_poll(data->drdy_trig); + + return IRQ_HANDLED; +} + static int ccs811_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -346,16 +391,48 @@ static int ccs811_probe(struct i2c_client *client, indio_dev->dev.parent = &client->dev; indio_dev->name = id->name; indio_dev->info = &ccs811_info; + indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->channels = ccs811_channels; indio_dev->num_channels = ARRAY_SIZE(ccs811_channels); + if (client->irq > 0) { + ret = devm_request_threaded_irq(&client->dev, client->irq, + ccs811_data_rdy_trigger_poll, + NULL, + IRQF_TRIGGER_FALLING | + IRQF_ONESHOT, + "ccs811_irq", indio_dev); + if (ret) { + dev_err(&client->dev, "irq request error %d\n", -ret); + goto err_poweroff; + } + + data->drdy_trig = devm_iio_trigger_alloc(&client->dev, + "%s-dev%d", + indio_dev->name, + indio_dev->id); + if (!data->drdy_trig) { + ret = -ENOMEM; + goto err_poweroff; + } + + data->drdy_trig->dev.parent = &client->dev; + data->drdy_trig->ops = &ccs811_trigger_ops; + iio_trigger_set_drvdata(data->drdy_trig, indio_dev); + indio_dev->trig = data->drdy_trig; + iio_trigger_get(indio_dev->trig); + ret = iio_trigger_register(data->drdy_trig); + if (ret) + goto err_poweroff; + } + ret = iio_triggered_buffer_setup(indio_dev, NULL, ccs811_trigger_handler, NULL); if (ret < 0) { dev_err(&client->dev, "triggered buffer setup failed\n"); - goto err_poweroff; + goto err_trigger_unregister; } ret = iio_device_register(indio_dev); @@ -367,6 +444,9 @@ static int ccs811_probe(struct i2c_client *client, err_buffer_cleanup: iio_triggered_buffer_cleanup(indio_dev); +err_trigger_unregister: + if (data->drdy_trig) + iio_trigger_unregister(data->drdy_trig); err_poweroff: i2c_smbus_write_byte_data(client, CCS811_MEAS_MODE, CCS811_MODE_IDLE); @@ -376,9 +456,12 @@ err_poweroff: static int ccs811_remove(struct i2c_client *client) { struct iio_dev *indio_dev = i2c_get_clientdata(client); + struct ccs811_data *data = iio_priv(indio_dev); iio_device_unregister(indio_dev); iio_triggered_buffer_cleanup(indio_dev); + if (data->drdy_trig) + iio_trigger_unregister(data->drdy_trig); return i2c_smbus_write_byte_data(client, CCS811_MEAS_MODE, CCS811_MODE_IDLE); diff --git a/drivers/iio/chemical/vz89x.c b/drivers/iio/chemical/vz89x.c index f75eea6822f2..9c9095ba4227 100644 --- a/drivers/iio/chemical/vz89x.c +++ b/drivers/iio/chemical/vz89x.c @@ -326,7 +326,6 @@ static int vz89x_read_raw(struct iio_dev *indio_dev, static const struct iio_info vz89x_info = { .attrs = &vz89x_attrs_group, .read_raw = vz89x_read_raw, - .driver_module = THIS_MODULE, }; static const struct vz89x_chip_data vz89x_chips[] = { diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c index 38e8783e4b05..ed8063f2da99 100644 --- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c +++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c @@ -185,7 +185,6 @@ static int cros_ec_sensors_write(struct iio_dev *indio_dev, static const struct iio_info ec_sensors_info = { .read_raw = &cros_ec_sensors_read, .write_raw = &cros_ec_sensors_write, - .driver_module = THIS_MODULE, }; static int cros_ec_sensors_probe(struct platform_device *pdev) diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c index 0e4b379ada45..cfb6588565ba 100644 --- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c +++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c @@ -179,6 +179,10 @@ int hid_sensor_power_state(struct hid_sensor_common *st, bool state) int ret; atomic_set(&st->user_requested_state, state); + + if (atomic_add_unless(&st->runtime_pm_enable, 1, 1)) + pm_runtime_enable(&st->pdev->dev); + if (state) ret = pm_runtime_get_sync(&st->pdev->dev); else { @@ -221,7 +225,8 @@ static void hid_sensor_set_power_work(struct work_struct *work) if (attrb->latency_ms > 0) hid_sensor_set_report_latency(attrb, attrb->latency_ms); - _hid_sensor_power_state(attrb, true); + if (atomic_read(&attrb->user_requested_state)) + _hid_sensor_power_state(attrb, true); } static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig, @@ -232,7 +237,9 @@ static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig, void hid_sensor_remove_trigger(struct hid_sensor_common *attrb) { - pm_runtime_disable(&attrb->pdev->dev); + if (atomic_read(&attrb->runtime_pm_enable)) + pm_runtime_disable(&attrb->pdev->dev); + pm_runtime_set_suspended(&attrb->pdev->dev); pm_runtime_put_noidle(&attrb->pdev->dev); @@ -243,7 +250,6 @@ void hid_sensor_remove_trigger(struct hid_sensor_common *attrb) EXPORT_SYMBOL(hid_sensor_remove_trigger); static const struct iio_trigger_ops hid_sensor_trigger_ops = { - .owner = THIS_MODULE, .set_trigger_state = &hid_sensor_data_rdy_trigger_set_state, }; @@ -283,7 +289,6 @@ int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name, INIT_WORK(&attrb->work, hid_sensor_set_power_work); pm_suspend_ignore_children(&attrb->pdev->dev, true); - pm_runtime_enable(&attrb->pdev->dev); /* Default to 3 seconds, but can be changed from sysfs */ pm_runtime_set_autosuspend_delay(&attrb->pdev->dev, 3000); diff --git a/drivers/iio/common/ssp_sensors/ssp_dev.c b/drivers/iio/common/ssp_sensors/ssp_dev.c index ea7adb638d99..2ba2ff5e59c4 100644 --- a/drivers/iio/common/ssp_sensors/ssp_dev.c +++ b/drivers/iio/common/ssp_sensors/ssp_dev.c @@ -175,9 +175,9 @@ static void ssp_wdt_work_func(struct work_struct *work) data->timeout_cnt = 0; } -static void ssp_wdt_timer_func(unsigned long ptr) +static void ssp_wdt_timer_func(struct timer_list *t) { - struct ssp_data *data = (struct ssp_data *)ptr; + struct ssp_data *data = from_timer(data, t, wdt_timer); switch (data->fw_dl_state) { case SSP_FW_DL_STATE_FAIL: @@ -571,7 +571,7 @@ static int ssp_probe(struct spi_device *spi) INIT_WORK(&data->work_wdt, ssp_wdt_work_func); INIT_DELAYED_WORK(&data->work_refresh, ssp_refresh_task); - setup_timer(&data->wdt_timer, ssp_wdt_timer_func, (unsigned long)data); + timer_setup(&data->wdt_timer, ssp_wdt_timer_func, 0); ret = request_threaded_irq(data->spi->irq, NULL, ssp_irq_thread_fn, diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c index 02e833b14db0..57db19182e95 100644 --- a/drivers/iio/common/st_sensors/st_sensors_core.c +++ b/drivers/iio/common/st_sensors/st_sensors_core.c @@ -93,6 +93,9 @@ int st_sensors_set_odr(struct iio_dev *indio_dev, unsigned int odr) struct st_sensor_odr_avl odr_out = {0, 0}; struct st_sensor_data *sdata = iio_priv(indio_dev); + if (!sdata->sensor_settings->odr.addr) + return 0; + err = st_sensors_match_odr(sdata->sensor_settings, odr, &odr_out); if (err < 0) goto st_sensors_match_odr_error; @@ -221,11 +224,14 @@ EXPORT_SYMBOL(st_sensors_set_enable); int st_sensors_set_axis_enable(struct iio_dev *indio_dev, u8 axis_enable) { struct st_sensor_data *sdata = iio_priv(indio_dev); + int err = 0; - return st_sensors_write_data_with_mask(indio_dev, + if (sdata->sensor_settings->enable_axis.addr) + err = st_sensors_write_data_with_mask(indio_dev, sdata->sensor_settings->enable_axis.addr, sdata->sensor_settings->enable_axis.mask, axis_enable); + return err; } EXPORT_SYMBOL(st_sensors_set_axis_enable); @@ -283,7 +289,8 @@ static int st_sensors_set_drdy_int_pin(struct iio_dev *indio_dev, struct st_sensor_data *sdata = iio_priv(indio_dev); /* Sensor does not support interrupts */ - if (sdata->sensor_settings->drdy_irq.addr == 0) { + if (!sdata->sensor_settings->drdy_irq.int1.addr && + !sdata->sensor_settings->drdy_irq.int2.addr) { if (pdata->drdy_int_pin) dev_info(&indio_dev->dev, "DRDY on pin INT%d specified, but sensor " @@ -294,7 +301,7 @@ static int st_sensors_set_drdy_int_pin(struct iio_dev *indio_dev, switch (pdata->drdy_int_pin) { case 1: - if (sdata->sensor_settings->drdy_irq.mask_int1 == 0) { + if (!sdata->sensor_settings->drdy_irq.int1.mask) { dev_err(&indio_dev->dev, "DRDY on INT1 not available.\n"); return -EINVAL; @@ -302,7 +309,7 @@ static int st_sensors_set_drdy_int_pin(struct iio_dev *indio_dev, sdata->drdy_int_pin = 1; break; case 2: - if (sdata->sensor_settings->drdy_irq.mask_int2 == 0) { + if (!sdata->sensor_settings->drdy_irq.int2.mask) { dev_err(&indio_dev->dev, "DRDY on INT2 not available.\n"); return -EINVAL; @@ -315,7 +322,8 @@ static int st_sensors_set_drdy_int_pin(struct iio_dev *indio_dev, } if (pdata->open_drain) { - if (!sdata->sensor_settings->drdy_irq.addr_od) + if (!sdata->sensor_settings->drdy_irq.int1.addr_od && + !sdata->sensor_settings->drdy_irq.int2.addr_od) dev_err(&indio_dev->dev, "open drain requested but unsupported.\n"); else @@ -442,11 +450,21 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev, } if (sdata->int_pin_open_drain) { + u8 addr, mask; + + if (sdata->drdy_int_pin == 1) { + addr = sdata->sensor_settings->drdy_irq.int1.addr_od; + mask = sdata->sensor_settings->drdy_irq.int1.mask_od; + } else { + addr = sdata->sensor_settings->drdy_irq.int2.addr_od; + mask = sdata->sensor_settings->drdy_irq.int2.mask_od; + } + dev_info(&indio_dev->dev, - "set interrupt line to open drain mode\n"); - err = st_sensors_write_data_with_mask(indio_dev, - sdata->sensor_settings->drdy_irq.addr_od, - sdata->sensor_settings->drdy_irq.mask_od, 1); + "set interrupt line to open drain mode on pin %d\n", + sdata->drdy_int_pin); + err = st_sensors_write_data_with_mask(indio_dev, addr, + mask, 1); if (err < 0) return err; } @@ -460,17 +478,18 @@ EXPORT_SYMBOL(st_sensors_init_sensor); int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable) { int err; - u8 drdy_mask; + u8 drdy_addr, drdy_mask; struct st_sensor_data *sdata = iio_priv(indio_dev); - if (!sdata->sensor_settings->drdy_irq.addr) { + if (!sdata->sensor_settings->drdy_irq.int1.addr && + !sdata->sensor_settings->drdy_irq.int2.addr) { /* * there are some devices (e.g. LIS3MDL) where drdy line is * routed to a given pin and it is not possible to select a * different one. Take into account irq status register * to understand if irq trigger can be properly supported */ - if (sdata->sensor_settings->drdy_irq.addr_stat_drdy) + if (sdata->sensor_settings->drdy_irq.stat_drdy.addr) sdata->hw_irq_trigger = enable; return 0; } @@ -485,18 +504,20 @@ int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable) goto st_accel_set_dataready_irq_error; } - if (sdata->drdy_int_pin == 1) - drdy_mask = sdata->sensor_settings->drdy_irq.mask_int1; - else - drdy_mask = sdata->sensor_settings->drdy_irq.mask_int2; + if (sdata->drdy_int_pin == 1) { + drdy_addr = sdata->sensor_settings->drdy_irq.int1.addr; + drdy_mask = sdata->sensor_settings->drdy_irq.int1.mask; + } else { + drdy_addr = sdata->sensor_settings->drdy_irq.int2.addr; + drdy_mask = sdata->sensor_settings->drdy_irq.int2.mask; + } /* Flag to the poll function that the hardware trigger is in use */ sdata->hw_irq_trigger = enable; /* Enable/Disable the interrupt generator for data ready. */ - err = st_sensors_write_data_with_mask(indio_dev, - sdata->sensor_settings->drdy_irq.addr, - drdy_mask, (int)enable); + err = st_sensors_write_data_with_mask(indio_dev, drdy_addr, + drdy_mask, (int)enable); st_accel_set_dataready_irq_error: return err; diff --git a/drivers/iio/common/st_sensors/st_sensors_trigger.c b/drivers/iio/common/st_sensors/st_sensors_trigger.c index fa73e6795359..fdcc5a891958 100644 --- a/drivers/iio/common/st_sensors/st_sensors_trigger.c +++ b/drivers/iio/common/st_sensors/st_sensors_trigger.c @@ -31,7 +31,7 @@ static int st_sensors_new_samples_available(struct iio_dev *indio_dev, int ret; /* How would I know if I can't check it? */ - if (!sdata->sensor_settings->drdy_irq.addr_stat_drdy) + if (!sdata->sensor_settings->drdy_irq.stat_drdy.addr) return -EINVAL; /* No scan mask, no interrupt */ @@ -39,23 +39,15 @@ static int st_sensors_new_samples_available(struct iio_dev *indio_dev, return 0; ret = sdata->tf->read_byte(&sdata->tb, sdata->dev, - sdata->sensor_settings->drdy_irq.addr_stat_drdy, + sdata->sensor_settings->drdy_irq.stat_drdy.addr, &status); if (ret < 0) { dev_err(sdata->dev, "error checking samples available\n"); return ret; } - /* - * the lower bits of .active_scan_mask[0] is directly mapped - * to the channels on the sensor: either bit 0 for - * one-dimensional sensors, or e.g. x,y,z for accelerometers, - * gyroscopes or magnetometers. No sensor use more than 3 - * channels, so cut the other status bits here. - */ - status &= 0x07; - if (status & (u8)indio_dev->active_scan_mask[0]) + if (status & sdata->sensor_settings->drdy_irq.stat_drdy.mask) return 1; return 0; @@ -212,7 +204,7 @@ int st_sensors_allocate_trigger(struct iio_dev *indio_dev, * it was "our" interrupt. */ if (sdata->int_pin_open_drain && - sdata->sensor_settings->drdy_irq.addr_stat_drdy) + sdata->sensor_settings->drdy_irq.stat_drdy.addr) irq_trig |= IRQF_SHARED; err = request_threaded_irq(sdata->get_irq_data_ready(indio_dev), diff --git a/drivers/iio/counter/104-quad-8.c b/drivers/iio/counter/104-quad-8.c index ba3d9030cd51..b56985078d8c 100644 --- a/drivers/iio/counter/104-quad-8.c +++ b/drivers/iio/counter/104-quad-8.c @@ -185,7 +185,6 @@ static int quad8_write_raw(struct iio_dev *indio_dev, } static const struct iio_info quad8_info = { - .driver_module = THIS_MODULE, .read_raw = quad8_read_raw, .write_raw = quad8_write_raw }; diff --git a/drivers/iio/counter/stm32-lptimer-cnt.c b/drivers/iio/counter/stm32-lptimer-cnt.c index 1c5909bb1605..81ae5f74216d 100644 --- a/drivers/iio/counter/stm32-lptimer-cnt.c +++ b/drivers/iio/counter/stm32-lptimer-cnt.c @@ -178,7 +178,6 @@ static int stm32_lptim_read_raw(struct iio_dev *indio_dev, static const struct iio_info stm32_lptim_cnt_iio_info = { .read_raw = stm32_lptim_read_raw, .write_raw = stm32_lptim_write_raw, - .driver_module = THIS_MODULE, }; static const char *const stm32_lptim_quadrature_modes[] = { diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index 25bed2d7d2b9..965d5c0d2468 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig @@ -60,7 +60,8 @@ config AD5446 Say yes here to build support for Analog Devices AD5300, AD5301, AD5310, AD5311, AD5320, AD5321, AD5444, AD5446, AD5450, AD5451, AD5452, AD5453, AD5512A, AD5541A, AD5542A, AD5543, AD5553, AD5601, AD5602, AD5611, AD5612, - AD5620, AD5621, AD5622, AD5640, AD5641, AD5660, AD5662 DACs. + AD5620, AD5621, AD5622, AD5640, AD5641, AD5660, AD5662 DACs + as well as Texas Instruments DAC081S101, DAC101S101, DAC121S101. To compile this driver as a module, choose M here: the module will be called ad5446. @@ -221,6 +222,15 @@ config DPOT_DAC To compile this driver as a module, choose M here: the module will be called dpot-dac. +config DS4424 + tristate "Maxim Integrated DS4422/DS4424 DAC driver" + depends on I2C + help + If you say yes here you get support for Maxim chips DS4422, DS4424. + + This driver can also be built as a module. If so, the module + will be called ds4424. + config LPC18XX_DAC tristate "NXP LPC18xx DAC driver" depends on ARCH_LPC18XX || COMPILE_TEST @@ -300,6 +310,16 @@ config STM32_DAC config STM32_DAC_CORE tristate +config TI_DAC082S085 + tristate "Texas Instruments 8/10/12-bit 2/4-channel DAC driver" + depends on SPI_MASTER + help + Driver for the Texas Instruments (formerly National Semiconductor) + DAC082S085, DAC102S085, DAC122S085, DAC084S085, DAC104S085 and + DAC124S085. + + If compiled as a module, it will be called ti-dac082s085. + config VF610_DAC tristate "Vybrid vf610 DAC driver" depends on OF diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile index 993511ba4b17..81e710ed7491 100644 --- a/drivers/iio/dac/Makefile +++ b/drivers/iio/dac/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_AD7303) += ad7303.o obj-$(CONFIG_AD8801) += ad8801.o obj-$(CONFIG_CIO_DAC) += cio-dac.o obj-$(CONFIG_DPOT_DAC) += dpot-dac.o +obj-$(CONFIG_DS4424) += ds4424.o obj-$(CONFIG_LPC18XX_DAC) += lpc18xx_dac.o obj-$(CONFIG_LTC2632) += ltc2632.o obj-$(CONFIG_M62332) += m62332.o @@ -33,4 +34,5 @@ obj-$(CONFIG_MCP4725) += mcp4725.o obj-$(CONFIG_MCP4922) += mcp4922.o obj-$(CONFIG_STM32_DAC_CORE) += stm32-dac-core.o obj-$(CONFIG_STM32_DAC) += stm32-dac.o +obj-$(CONFIG_TI_DAC082S085) += ti-dac082s085.o obj-$(CONFIG_VF610_DAC) += vf610_dac.o diff --git a/drivers/iio/dac/ad5064.c b/drivers/iio/dac/ad5064.c index 3f9399c27869..bf4fc40ec84d 100644 --- a/drivers/iio/dac/ad5064.c +++ b/drivers/iio/dac/ad5064.c @@ -366,7 +366,6 @@ static int ad5064_write_raw(struct iio_dev *indio_dev, static const struct iio_info ad5064_info = { .read_raw = ad5064_read_raw, .write_raw = ad5064_write_raw, - .driver_module = THIS_MODULE, }; static const struct iio_chan_spec_ext_info ad5064_ext_info[] = { diff --git a/drivers/iio/dac/ad5360.c b/drivers/iio/dac/ad5360.c index 8ba0e9c50176..0209316d5566 100644 --- a/drivers/iio/dac/ad5360.c +++ b/drivers/iio/dac/ad5360.c @@ -425,7 +425,6 @@ static const struct iio_info ad5360_info = { .read_raw = ad5360_read_raw, .write_raw = ad5360_write_raw, .attrs = &ad5360_attribute_group, - .driver_module = THIS_MODULE, }; static const char * const ad5360_vref_name[] = { diff --git a/drivers/iio/dac/ad5380.c b/drivers/iio/dac/ad5380.c index 97d2c5111f43..845fd1c0fd9d 100644 --- a/drivers/iio/dac/ad5380.c +++ b/drivers/iio/dac/ad5380.c @@ -237,7 +237,6 @@ static int ad5380_read_raw(struct iio_dev *indio_dev, static const struct iio_info ad5380_info = { .read_raw = ad5380_read_raw, .write_raw = ad5380_write_raw, - .driver_module = THIS_MODULE, }; static struct iio_chan_spec_ext_info ad5380_ext_info[] = { diff --git a/drivers/iio/dac/ad5421.c b/drivers/iio/dac/ad5421.c index 559061ab1982..8e9633d8de67 100644 --- a/drivers/iio/dac/ad5421.c +++ b/drivers/iio/dac/ad5421.c @@ -465,7 +465,6 @@ static const struct iio_info ad5421_info = { .read_event_config = ad5421_read_event_config, .write_event_config = ad5421_write_event_config, .read_event_value = ad5421_read_event_value, - .driver_module = THIS_MODULE, }; static int ad5421_probe(struct spi_device *spi) diff --git a/drivers/iio/dac/ad5446.c b/drivers/iio/dac/ad5446.c index b555552a0d80..fd26a4272fc5 100644 --- a/drivers/iio/dac/ad5446.c +++ b/drivers/iio/dac/ad5446.c @@ -212,7 +212,6 @@ static int ad5446_write_raw(struct iio_dev *indio_dev, static const struct iio_info ad5446_info = { .read_raw = ad5446_read_raw, .write_raw = ad5446_write_raw, - .driver_module = THIS_MODULE, }; static int ad5446_probe(struct device *dev, const char *name, @@ -461,10 +460,22 @@ static const struct spi_device_id ad5446_spi_ids[] = { {"ad5660-2500", ID_AD5660_2500}, {"ad5660-1250", ID_AD5660_1250}, {"ad5662", ID_AD5662}, + {"dac081s101", ID_AD5300}, /* compatible Texas Instruments chips */ + {"dac101s101", ID_AD5310}, + {"dac121s101", ID_AD5320}, + {"dac7512", ID_AD5320}, {} }; MODULE_DEVICE_TABLE(spi, ad5446_spi_ids); +#ifdef CONFIG_OF +static const struct of_device_id ad5446_of_ids[] = { + { .compatible = "ti,dac7512" }, + { } +}; +MODULE_DEVICE_TABLE(of, ad5446_of_ids); +#endif + static int ad5446_spi_probe(struct spi_device *spi) { const struct spi_device_id *id = spi_get_device_id(spi); @@ -481,6 +492,7 @@ static int ad5446_spi_remove(struct spi_device *spi) static struct spi_driver ad5446_spi_driver = { .driver = { .name = "ad5446", + .of_match_table = of_match_ptr(ad5446_of_ids), }, .probe = ad5446_spi_probe, .remove = ad5446_spi_remove, diff --git a/drivers/iio/dac/ad5449.c b/drivers/iio/dac/ad5449.c index 5f3202339420..317a74129932 100644 --- a/drivers/iio/dac/ad5449.c +++ b/drivers/iio/dac/ad5449.c @@ -193,7 +193,6 @@ static int ad5449_write_raw(struct iio_dev *indio_dev, static const struct iio_info ad5449_info = { .read_raw = ad5449_read_raw, .write_raw = ad5449_write_raw, - .driver_module = THIS_MODULE, }; #define AD5449_CHANNEL(chan, bits) { \ diff --git a/drivers/iio/dac/ad5504.c b/drivers/iio/dac/ad5504.c index 712d86b4be09..d9037ea59168 100644 --- a/drivers/iio/dac/ad5504.c +++ b/drivers/iio/dac/ad5504.c @@ -232,7 +232,6 @@ static const struct iio_info ad5504_info = { .write_raw = ad5504_write_raw, .read_raw = ad5504_read_raw, .event_attrs = &ad5504_ev_attribute_group, - .driver_module = THIS_MODULE, }; static const struct iio_chan_spec_ext_info ad5504_ext_info[] = { diff --git a/drivers/iio/dac/ad5592r-base.c b/drivers/iio/dac/ad5592r-base.c index 69bde5909854..9234c6a09a93 100644 --- a/drivers/iio/dac/ad5592r-base.c +++ b/drivers/iio/dac/ad5592r-base.c @@ -474,7 +474,6 @@ static const struct iio_info ad5592r_info = { .read_raw = ad5592r_read_raw, .write_raw = ad5592r_write_raw, .write_raw_get_fmt = ad5592r_write_raw_get_fmt, - .driver_module = THIS_MODULE, }; static ssize_t ad5592r_show_scale_available(struct iio_dev *iio_dev, diff --git a/drivers/iio/dac/ad5624r_spi.c b/drivers/iio/dac/ad5624r_spi.c index 5489ec43b95d..13fdb4dfe356 100644 --- a/drivers/iio/dac/ad5624r_spi.c +++ b/drivers/iio/dac/ad5624r_spi.c @@ -149,7 +149,6 @@ static ssize_t ad5624r_write_dac_powerdown(struct iio_dev *indio_dev, static const struct iio_info ad5624r_info = { .write_raw = ad5624r_write_raw, .read_raw = ad5624r_read_raw, - .driver_module = THIS_MODULE, }; static const struct iio_chan_spec_ext_info ad5624r_ext_info[] = { diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c index d1d8450c19f6..20254df7f9c7 100644 --- a/drivers/iio/dac/ad5686.c +++ b/drivers/iio/dac/ad5686.c @@ -252,7 +252,6 @@ static int ad5686_write_raw(struct iio_dev *indio_dev, static const struct iio_info ad5686_info = { .read_raw = ad5686_read_raw, .write_raw = ad5686_write_raw, - .driver_module = THIS_MODULE, }; static const struct iio_chan_spec_ext_info ad5686_ext_info[] = { diff --git a/drivers/iio/dac/ad5755.c b/drivers/iio/dac/ad5755.c index 5f7968232564..2d03cc89ba50 100644 --- a/drivers/iio/dac/ad5755.c +++ b/drivers/iio/dac/ad5755.c @@ -417,7 +417,6 @@ static ssize_t ad5755_write_powerdown(struct iio_dev *indio_dev, uintptr_t priv, static const struct iio_info ad5755_info = { .read_raw = ad5755_read_raw, .write_raw = ad5755_write_raw, - .driver_module = THIS_MODULE, }; static const struct iio_chan_spec_ext_info ad5755_ext_info[] = { diff --git a/drivers/iio/dac/ad5761.c b/drivers/iio/dac/ad5761.c index d6510d6928b3..05017c8bbd00 100644 --- a/drivers/iio/dac/ad5761.c +++ b/drivers/iio/dac/ad5761.c @@ -251,7 +251,6 @@ static int ad5761_write_raw(struct iio_dev *indio_dev, static const struct iio_info ad5761_info = { .read_raw = &ad5761_read_raw, .write_raw = &ad5761_write_raw, - .driver_module = THIS_MODULE, }; #define AD5761_CHAN(_bits) { \ diff --git a/drivers/iio/dac/ad5764.c b/drivers/iio/dac/ad5764.c index 9a547bbf7d2b..033f20eca616 100644 --- a/drivers/iio/dac/ad5764.c +++ b/drivers/iio/dac/ad5764.c @@ -268,7 +268,6 @@ static int ad5764_read_raw(struct iio_dev *indio_dev, static const struct iio_info ad5764_info = { .read_raw = ad5764_read_raw, .write_raw = ad5764_write_raw, - .driver_module = THIS_MODULE, }; static int ad5764_probe(struct spi_device *spi) diff --git a/drivers/iio/dac/ad5791.c b/drivers/iio/dac/ad5791.c index 33e4ae5c42f8..7569bf6868c2 100644 --- a/drivers/iio/dac/ad5791.c +++ b/drivers/iio/dac/ad5791.c @@ -340,7 +340,6 @@ static int ad5791_write_raw(struct iio_dev *indio_dev, static const struct iio_info ad5791_info = { .read_raw = &ad5791_read_raw, .write_raw = &ad5791_write_raw, - .driver_module = THIS_MODULE, }; static int ad5791_probe(struct spi_device *spi) diff --git a/drivers/iio/dac/ad7303.c b/drivers/iio/dac/ad7303.c index 4b0f942b8914..8f3bd19b6dc3 100644 --- a/drivers/iio/dac/ad7303.c +++ b/drivers/iio/dac/ad7303.c @@ -161,7 +161,6 @@ static int ad7303_write_raw(struct iio_dev *indio_dev, static const struct iio_info ad7303_info = { .read_raw = ad7303_read_raw, .write_raw = ad7303_write_raw, - .driver_module = THIS_MODULE, }; static const struct iio_chan_spec_ext_info ad7303_ext_info[] = { diff --git a/drivers/iio/dac/ad8801.c b/drivers/iio/dac/ad8801.c index f06faa1aec09..aef5808c9865 100644 --- a/drivers/iio/dac/ad8801.c +++ b/drivers/iio/dac/ad8801.c @@ -92,7 +92,6 @@ static int ad8801_read_raw(struct iio_dev *indio_dev, static const struct iio_info ad8801_info = { .read_raw = ad8801_read_raw, .write_raw = ad8801_write_raw, - .driver_module = THIS_MODULE, }; #define AD8801_CHANNEL(chan) { \ diff --git a/drivers/iio/dac/cio-dac.c b/drivers/iio/dac/cio-dac.c index a8dffd938615..6898b0c79013 100644 --- a/drivers/iio/dac/cio-dac.c +++ b/drivers/iio/dac/cio-dac.c @@ -85,7 +85,6 @@ static int cio_dac_write_raw(struct iio_dev *indio_dev, } static const struct iio_info cio_dac_info = { - .driver_module = THIS_MODULE, .read_raw = cio_dac_read_raw, .write_raw = cio_dac_write_raw }; diff --git a/drivers/iio/dac/dpot-dac.c b/drivers/iio/dac/dpot-dac.c index 960a2b430480..aaa2103d7c2b 100644 --- a/drivers/iio/dac/dpot-dac.c +++ b/drivers/iio/dac/dpot-dac.c @@ -128,7 +128,6 @@ static const struct iio_info dpot_dac_info = { .read_raw = dpot_dac_read_raw, .read_avail = dpot_dac_read_avail, .write_raw = dpot_dac_write_raw, - .driver_module = THIS_MODULE, }; static int dpot_dac_channel_max_ohms(struct iio_dev *indio_dev) diff --git a/drivers/iio/dac/ds4424.c b/drivers/iio/dac/ds4424.c new file mode 100644 index 000000000000..883a47562055 --- /dev/null +++ b/drivers/iio/dac/ds4424.c @@ -0,0 +1,341 @@ +/* + * Maxim Integrated + * 7-bit, Multi-Channel Sink/Source Current DAC Driver + * Copyright (C) 2017 Maxim Integrated + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/i2c.h> +#include <linux/regulator/consumer.h> +#include <linux/err.h> +#include <linux/delay.h> +#include <linux/iio/iio.h> +#include <linux/iio/driver.h> +#include <linux/iio/machine.h> +#include <linux/iio/consumer.h> + +#define DS4422_MAX_DAC_CHANNELS 2 +#define DS4424_MAX_DAC_CHANNELS 4 + +#define DS4424_DAC_ADDR(chan) ((chan) + 0xf8) +#define DS4424_SOURCE_I 1 +#define DS4424_SINK_I 0 + +#define DS4424_CHANNEL(chan) { \ + .type = IIO_CURRENT, \ + .indexed = 1, \ + .output = 1, \ + .channel = chan, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ +} + +/* + * DS4424 DAC control register 8 bits + * [7] 0: to sink; 1: to source + * [6:0] steps to sink/source + * bit[7] looks like a sign bit, but the value of the register is + * not a two's complement code considering the bit[6:0] is a absolute + * distance from the zero point. + */ +union ds4424_raw_data { + struct { + u8 dx:7; + u8 source_bit:1; + }; + u8 bits; +}; + +enum ds4424_device_ids { + ID_DS4422, + ID_DS4424, +}; + +struct ds4424_data { + struct i2c_client *client; + struct mutex lock; + uint8_t save[DS4424_MAX_DAC_CHANNELS]; + struct regulator *vcc_reg; + uint8_t raw[DS4424_MAX_DAC_CHANNELS]; +}; + +static const struct iio_chan_spec ds4424_channels[] = { + DS4424_CHANNEL(0), + DS4424_CHANNEL(1), + DS4424_CHANNEL(2), + DS4424_CHANNEL(3), +}; + +static int ds4424_get_value(struct iio_dev *indio_dev, + int *val, int channel) +{ + struct ds4424_data *data = iio_priv(indio_dev); + int ret; + + mutex_lock(&data->lock); + ret = i2c_smbus_read_byte_data(data->client, DS4424_DAC_ADDR(channel)); + if (ret < 0) + goto fail; + + *val = ret; + +fail: + mutex_unlock(&data->lock); + return ret; +} + +static int ds4424_set_value(struct iio_dev *indio_dev, + int val, struct iio_chan_spec const *chan) +{ + struct ds4424_data *data = iio_priv(indio_dev); + int ret; + + mutex_lock(&data->lock); + ret = i2c_smbus_write_byte_data(data->client, + DS4424_DAC_ADDR(chan->channel), val); + if (ret < 0) + goto fail; + + data->raw[chan->channel] = val; + +fail: + mutex_unlock(&data->lock); + return ret; +} + +static int ds4424_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + union ds4424_raw_data raw; + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret = ds4424_get_value(indio_dev, val, chan->channel); + if (ret < 0) { + pr_err("%s : ds4424_get_value returned %d\n", + __func__, ret); + return ret; + } + raw.bits = *val; + *val = raw.dx; + if (raw.source_bit == DS4424_SINK_I) + *val = -*val; + return IIO_VAL_INT; + + default: + return -EINVAL; + } +} + +static int ds4424_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + union ds4424_raw_data raw; + + if (val2 != 0) + return -EINVAL; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + if (val < S8_MIN || val > S8_MAX) + return -EINVAL; + + if (val > 0) { + raw.source_bit = DS4424_SOURCE_I; + raw.dx = val; + } else { + raw.source_bit = DS4424_SINK_I; + raw.dx = -val; + } + + return ds4424_set_value(indio_dev, raw.bits, chan); + + default: + return -EINVAL; + } +} + +static int ds4424_verify_chip(struct iio_dev *indio_dev) +{ + int ret, val; + + ret = ds4424_get_value(indio_dev, &val, DS4424_DAC_ADDR(0)); + if (ret < 0) + dev_err(&indio_dev->dev, + "%s failed. ret: %d\n", __func__, ret); + + return ret; +} + +static int __maybe_unused ds4424_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct iio_dev *indio_dev = i2c_get_clientdata(client); + struct ds4424_data *data = iio_priv(indio_dev); + int ret = 0; + int i; + + for (i = 0; i < indio_dev->num_channels; i++) { + data->save[i] = data->raw[i]; + ret = ds4424_set_value(indio_dev, 0, + &indio_dev->channels[i]); + if (ret < 0) + return ret; + } + return ret; +} + +static int __maybe_unused ds4424_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct iio_dev *indio_dev = i2c_get_clientdata(client); + struct ds4424_data *data = iio_priv(indio_dev); + int ret = 0; + int i; + + for (i = 0; i < indio_dev->num_channels; i++) { + ret = ds4424_set_value(indio_dev, data->save[i], + &indio_dev->channels[i]); + if (ret < 0) + return ret; + } + return ret; +} + +static SIMPLE_DEV_PM_OPS(ds4424_pm_ops, ds4424_suspend, ds4424_resume); + +static const struct iio_info ds4424_info = { + .read_raw = ds4424_read_raw, + .write_raw = ds4424_write_raw, +}; + +static int ds4424_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct ds4424_data *data; + struct iio_dev *indio_dev; + int ret; + + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); + if (!indio_dev) { + dev_err(&client->dev, "iio dev alloc failed.\n"); + return -ENOMEM; + } + + data = iio_priv(indio_dev); + i2c_set_clientdata(client, indio_dev); + data->client = client; + indio_dev->name = id->name; + indio_dev->dev.of_node = client->dev.of_node; + indio_dev->dev.parent = &client->dev; + + if (!client->dev.of_node) { + dev_err(&client->dev, + "Not found DT.\n"); + return -ENODEV; + } + + data->vcc_reg = devm_regulator_get(&client->dev, "vcc"); + if (IS_ERR(data->vcc_reg)) { + dev_err(&client->dev, + "Failed to get vcc-supply regulator. err: %ld\n", + PTR_ERR(data->vcc_reg)); + return PTR_ERR(data->vcc_reg); + } + + mutex_init(&data->lock); + ret = regulator_enable(data->vcc_reg); + if (ret < 0) { + dev_err(&client->dev, + "Unable to enable the regulator.\n"); + return ret; + } + + usleep_range(1000, 1200); + ret = ds4424_verify_chip(indio_dev); + if (ret < 0) + goto fail; + + switch (id->driver_data) { + case ID_DS4422: + indio_dev->num_channels = DS4422_MAX_DAC_CHANNELS; + break; + case ID_DS4424: + indio_dev->num_channels = DS4424_MAX_DAC_CHANNELS; + break; + default: + dev_err(&client->dev, + "ds4424: Invalid chip id.\n"); + ret = -ENXIO; + goto fail; + } + + indio_dev->channels = ds4424_channels; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &ds4424_info; + + ret = iio_device_register(indio_dev); + if (ret < 0) { + dev_err(&client->dev, + "iio_device_register failed. ret: %d\n", ret); + goto fail; + } + + return ret; + +fail: + regulator_disable(data->vcc_reg); + return ret; +} + +static int ds4424_remove(struct i2c_client *client) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(client); + struct ds4424_data *data = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + regulator_disable(data->vcc_reg); + + return 0; +} + +static const struct i2c_device_id ds4424_id[] = { + { "ds4422", ID_DS4422 }, + { "ds4424", ID_DS4424 }, + { } +}; + +MODULE_DEVICE_TABLE(i2c, ds4424_id); + +static const struct of_device_id ds4424_of_match[] = { + { .compatible = "maxim,ds4422" }, + { .compatible = "maxim,ds4424" }, + { }, +}; + +MODULE_DEVICE_TABLE(of, ds4424_of_match); + +static struct i2c_driver ds4424_driver = { + .driver = { + .name = "ds4424", + .of_match_table = ds4424_of_match, + .pm = &ds4424_pm_ops, + }, + .probe = ds4424_probe, + .remove = ds4424_remove, + .id_table = ds4424_id, +}; +module_i2c_driver(ds4424_driver); + +MODULE_DESCRIPTION("Maxim DS4424 DAC Driver"); +MODULE_AUTHOR("Ismail H. Kose <ismail.kose@maximintegrated.com>"); +MODULE_AUTHOR("Vishal Sood <vishal.sood@maximintegrated.com>"); +MODULE_AUTHOR("David Jung <david.jung@maximintegrated.com>"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/dac/lpc18xx_dac.c b/drivers/iio/dac/lpc18xx_dac.c index 55d1456a059d..7036f77fdf23 100644 --- a/drivers/iio/dac/lpc18xx_dac.c +++ b/drivers/iio/dac/lpc18xx_dac.c @@ -103,7 +103,6 @@ static int lpc18xx_dac_write_raw(struct iio_dev *indio_dev, static const struct iio_info lpc18xx_dac_info = { .read_raw = lpc18xx_dac_read_raw, .write_raw = lpc18xx_dac_write_raw, - .driver_module = THIS_MODULE, }; static int lpc18xx_dac_probe(struct platform_device *pdev) diff --git a/drivers/iio/dac/ltc2632.c b/drivers/iio/dac/ltc2632.c index ac5e05f6eb8b..af2ddd0dd341 100644 --- a/drivers/iio/dac/ltc2632.c +++ b/drivers/iio/dac/ltc2632.c @@ -159,7 +159,6 @@ static ssize_t ltc2632_write_dac_powerdown(struct iio_dev *indio_dev, static const struct iio_info ltc2632_info = { .write_raw = ltc2632_write_raw, .read_raw = ltc2632_read_raw, - .driver_module = THIS_MODULE, }; static const struct iio_chan_spec_ext_info ltc2632_ext_info[] = { diff --git a/drivers/iio/dac/m62332.c b/drivers/iio/dac/m62332.c index 76e8b044b979..19031943dabe 100644 --- a/drivers/iio/dac/m62332.c +++ b/drivers/iio/dac/m62332.c @@ -174,7 +174,6 @@ static SIMPLE_DEV_PM_OPS(m62332_pm_ops, m62332_suspend, m62332_resume); static const struct iio_info m62332_info = { .read_raw = m62332_read_raw, .write_raw = m62332_write_raw, - .driver_module = THIS_MODULE, }; #define M62332_CHANNEL(chan) { \ diff --git a/drivers/iio/dac/max517.c b/drivers/iio/dac/max517.c index 5507b3970b4b..1d853247a205 100644 --- a/drivers/iio/dac/max517.c +++ b/drivers/iio/dac/max517.c @@ -137,7 +137,6 @@ static SIMPLE_DEV_PM_OPS(max517_pm_ops, max517_suspend, max517_resume); static const struct iio_info max517_info = { .read_raw = max517_read_raw, .write_raw = max517_write_raw, - .driver_module = THIS_MODULE, }; #define MAX517_CHANNEL(chan) { \ diff --git a/drivers/iio/dac/max5821.c b/drivers/iio/dac/max5821.c index 193fac3059a3..d0ecc1fdd8fc 100644 --- a/drivers/iio/dac/max5821.c +++ b/drivers/iio/dac/max5821.c @@ -300,7 +300,6 @@ static SIMPLE_DEV_PM_OPS(max5821_pm_ops, max5821_suspend, max5821_resume); static const struct iio_info max5821_info = { .read_raw = max5821_read_raw, .write_raw = max5821_write_raw, - .driver_module = THIS_MODULE, }; static int max5821_probe(struct i2c_client *client, diff --git a/drivers/iio/dac/mcp4725.c b/drivers/iio/dac/mcp4725.c index 6ab1f23e5a79..afa856d10c26 100644 --- a/drivers/iio/dac/mcp4725.c +++ b/drivers/iio/dac/mcp4725.c @@ -363,7 +363,6 @@ static const struct iio_info mcp4725_info = { .read_raw = mcp4725_read_raw, .write_raw = mcp4725_write_raw, .attrs = &mcp4725_attribute_group, - .driver_module = THIS_MODULE, }; #ifdef CONFIG_OF diff --git a/drivers/iio/dac/mcp4922.c b/drivers/iio/dac/mcp4922.c index 3854d201a5d6..bf9aa3fc0534 100644 --- a/drivers/iio/dac/mcp4922.c +++ b/drivers/iio/dac/mcp4922.c @@ -119,7 +119,6 @@ static const struct iio_chan_spec mcp4922_channels[3][MCP4922_NUM_CHANNELS] = { static const struct iio_info mcp4922_info = { .read_raw = &mcp4922_read_raw, .write_raw = &mcp4922_write_raw, - .driver_module = THIS_MODULE, }; static int mcp4922_probe(struct spi_device *spi) diff --git a/drivers/iio/dac/stm32-dac.c b/drivers/iio/dac/stm32-dac.c index c1864e8aa851..9ffab02bf9f9 100644 --- a/drivers/iio/dac/stm32-dac.c +++ b/drivers/iio/dac/stm32-dac.c @@ -156,7 +156,6 @@ static const struct iio_info stm32_dac_iio_info = { .read_raw = stm32_dac_read_raw, .write_raw = stm32_dac_write_raw, .debugfs_reg_access = stm32_dac_debugfs_reg_access, - .driver_module = THIS_MODULE, }; static const char * const stm32_dac_powerdown_modes[] = { diff --git a/drivers/iio/dac/ti-dac082s085.c b/drivers/iio/dac/ti-dac082s085.c new file mode 100644 index 000000000000..4e1e28339c84 --- /dev/null +++ b/drivers/iio/dac/ti-dac082s085.c @@ -0,0 +1,368 @@ +/* + * ti-dac082s085.c - Texas Instruments 8/10/12-bit 2/4-channel DAC driver + * + * Copyright (C) 2017 KUNBUS GmbH + * + * http://www.ti.com/lit/ds/symlink/dac082s085.pdf + * http://www.ti.com/lit/ds/symlink/dac102s085.pdf + * http://www.ti.com/lit/ds/symlink/dac122s085.pdf + * http://www.ti.com/lit/ds/symlink/dac084s085.pdf + * http://www.ti.com/lit/ds/symlink/dac104s085.pdf + * http://www.ti.com/lit/ds/symlink/dac124s085.pdf + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License (version 2) as + * published by the Free Software Foundation. + */ + +#include <linux/iio/iio.h> +#include <linux/module.h> +#include <linux/regulator/consumer.h> +#include <linux/spi/spi.h> + +enum { dual_8bit, dual_10bit, dual_12bit, quad_8bit, quad_10bit, quad_12bit }; + +struct ti_dac_spec { + u8 num_channels; + u8 resolution; +}; + +static const struct ti_dac_spec ti_dac_spec[] = { + [dual_8bit] = { .num_channels = 2, .resolution = 8 }, + [dual_10bit] = { .num_channels = 2, .resolution = 10 }, + [dual_12bit] = { .num_channels = 2, .resolution = 12 }, + [quad_8bit] = { .num_channels = 4, .resolution = 8 }, + [quad_10bit] = { .num_channels = 4, .resolution = 10 }, + [quad_12bit] = { .num_channels = 4, .resolution = 12 }, +}; + +/** + * struct ti_dac_chip - TI DAC chip + * @lock: protects write sequences + * @vref: regulator generating Vref + * @mesg: SPI message to perform a write + * @xfer: SPI transfer used by @mesg + * @val: cached value of each output + * @powerdown: whether the chip is powered down + * @powerdown_mode: selected by the user + * @resolution: resolution of the chip + * @buf: buffer for @xfer + */ +struct ti_dac_chip { + struct mutex lock; + struct regulator *vref; + struct spi_message mesg; + struct spi_transfer xfer; + u16 val[4]; + bool powerdown; + u8 powerdown_mode; + u8 resolution; + u8 buf[2] ____cacheline_aligned; +}; + +#define WRITE_NOT_UPDATE(chan) (0x00 | (chan) << 6) +#define WRITE_AND_UPDATE(chan) (0x10 | (chan) << 6) +#define WRITE_ALL_UPDATE 0x20 +#define POWERDOWN(mode) (0x30 | ((mode) + 1) << 6) + +static int ti_dac_cmd(struct ti_dac_chip *ti_dac, u8 cmd, u16 val) +{ + u8 shift = 12 - ti_dac->resolution; + + ti_dac->buf[0] = cmd | (val >> (8 - shift)); + ti_dac->buf[1] = (val << shift) & 0xff; + return spi_sync(ti_dac->mesg.spi, &ti_dac->mesg); +} + +static const char * const ti_dac_powerdown_modes[] = { + "2.5kohm_to_gnd", "100kohm_to_gnd", "three_state", +}; + +static int ti_dac_get_powerdown_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) +{ + struct ti_dac_chip *ti_dac = iio_priv(indio_dev); + + return ti_dac->powerdown_mode; +} + +static int ti_dac_set_powerdown_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + unsigned int mode) +{ + struct ti_dac_chip *ti_dac = iio_priv(indio_dev); + int ret = 0; + + if (ti_dac->powerdown_mode == mode) + return 0; + + mutex_lock(&ti_dac->lock); + if (ti_dac->powerdown) { + ret = ti_dac_cmd(ti_dac, POWERDOWN(mode), 0); + if (ret) + goto out; + } + ti_dac->powerdown_mode = mode; + +out: + mutex_unlock(&ti_dac->lock); + return ret; +} + +static const struct iio_enum ti_dac_powerdown_mode = { + .items = ti_dac_powerdown_modes, + .num_items = ARRAY_SIZE(ti_dac_powerdown_modes), + .get = ti_dac_get_powerdown_mode, + .set = ti_dac_set_powerdown_mode, +}; + +static ssize_t ti_dac_read_powerdown(struct iio_dev *indio_dev, + uintptr_t private, + const struct iio_chan_spec *chan, + char *buf) +{ + struct ti_dac_chip *ti_dac = iio_priv(indio_dev); + + return sprintf(buf, "%d\n", ti_dac->powerdown); +} + +static ssize_t ti_dac_write_powerdown(struct iio_dev *indio_dev, + uintptr_t private, + const struct iio_chan_spec *chan, + const char *buf, size_t len) +{ + struct ti_dac_chip *ti_dac = iio_priv(indio_dev); + bool powerdown; + int ret; + + ret = strtobool(buf, &powerdown); + if (ret) + return ret; + + if (ti_dac->powerdown == powerdown) + return len; + + mutex_lock(&ti_dac->lock); + if (powerdown) + ret = ti_dac_cmd(ti_dac, POWERDOWN(ti_dac->powerdown_mode), 0); + else + ret = ti_dac_cmd(ti_dac, WRITE_AND_UPDATE(0), ti_dac->val[0]); + if (!ret) + ti_dac->powerdown = powerdown; + mutex_unlock(&ti_dac->lock); + + return ret ? ret : len; +} + +static const struct iio_chan_spec_ext_info ti_dac_ext_info[] = { + { + .name = "powerdown", + .read = ti_dac_read_powerdown, + .write = ti_dac_write_powerdown, + .shared = IIO_SHARED_BY_TYPE, + }, + IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE, &ti_dac_powerdown_mode), + IIO_ENUM_AVAILABLE("powerdown_mode", &ti_dac_powerdown_mode), + { }, +}; + +#define TI_DAC_CHANNEL(chan) { \ + .type = IIO_VOLTAGE, \ + .channel = (chan), \ + .address = (chan), \ + .indexed = true, \ + .output = true, \ + .datasheet_name = (const char[]){ 'A' + (chan), 0 }, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ + .ext_info = ti_dac_ext_info, \ +} + +static const struct iio_chan_spec ti_dac_channels[] = { + TI_DAC_CHANNEL(0), + TI_DAC_CHANNEL(1), + TI_DAC_CHANNEL(2), + TI_DAC_CHANNEL(3), +}; + +static int ti_dac_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct ti_dac_chip *ti_dac = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + *val = ti_dac->val[chan->channel]; + ret = IIO_VAL_INT; + break; + + case IIO_CHAN_INFO_SCALE: + ret = regulator_get_voltage(ti_dac->vref); + if (ret < 0) + return ret; + + *val = ret / 1000; + *val2 = ti_dac->resolution; + ret = IIO_VAL_FRACTIONAL_LOG2; + break; + + default: + ret = -EINVAL; + } + + return ret; +} + +static int ti_dac_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct ti_dac_chip *ti_dac = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + if (ti_dac->val[chan->channel] == val) + return 0; + + if (val >= (1 << ti_dac->resolution) || val < 0) + return -EINVAL; + + if (ti_dac->powerdown) + return -EBUSY; + + mutex_lock(&ti_dac->lock); + ret = ti_dac_cmd(ti_dac, WRITE_AND_UPDATE(chan->channel), val); + if (!ret) + ti_dac->val[chan->channel] = val; + mutex_unlock(&ti_dac->lock); + break; + + default: + ret = -EINVAL; + } + + return ret; +} + +static int ti_dac_write_raw_get_fmt(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, long mask) +{ + return IIO_VAL_INT; +} + +static const struct iio_info ti_dac_info = { + .read_raw = ti_dac_read_raw, + .write_raw = ti_dac_write_raw, + .write_raw_get_fmt = ti_dac_write_raw_get_fmt, +}; + +static int ti_dac_probe(struct spi_device *spi) +{ + struct device *dev = &spi->dev; + const struct ti_dac_spec *spec; + struct ti_dac_chip *ti_dac; + struct iio_dev *indio_dev; + int ret; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*ti_dac)); + if (!indio_dev) + return -ENOMEM; + + indio_dev->dev.parent = dev; + indio_dev->info = &ti_dac_info; + indio_dev->name = spi->modalias; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = ti_dac_channels; + spi_set_drvdata(spi, indio_dev); + + ti_dac = iio_priv(indio_dev); + ti_dac->xfer.tx_buf = &ti_dac->buf; + ti_dac->xfer.len = sizeof(ti_dac->buf); + spi_message_init_with_transfers(&ti_dac->mesg, &ti_dac->xfer, 1); + ti_dac->mesg.spi = spi; + + spec = &ti_dac_spec[spi_get_device_id(spi)->driver_data]; + indio_dev->num_channels = spec->num_channels; + ti_dac->resolution = spec->resolution; + + ti_dac->vref = devm_regulator_get(dev, "vref"); + if (IS_ERR(ti_dac->vref)) + return PTR_ERR(ti_dac->vref); + + ret = regulator_enable(ti_dac->vref); + if (ret < 0) + return ret; + + mutex_init(&ti_dac->lock); + + ret = ti_dac_cmd(ti_dac, WRITE_ALL_UPDATE, 0); + if (ret) { + dev_err(dev, "failed to initialize outputs to 0\n"); + goto err; + } + + ret = iio_device_register(indio_dev); + if (ret) + goto err; + + return 0; + +err: + mutex_destroy(&ti_dac->lock); + regulator_disable(ti_dac->vref); + return ret; +} + +static int ti_dac_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ti_dac_chip *ti_dac = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + mutex_destroy(&ti_dac->lock); + regulator_disable(ti_dac->vref); + + return 0; +} + +#ifdef CONFIG_OF +static const struct of_device_id ti_dac_of_id[] = { + { .compatible = "ti,dac082s085" }, + { .compatible = "ti,dac102s085" }, + { .compatible = "ti,dac122s085" }, + { .compatible = "ti,dac084s085" }, + { .compatible = "ti,dac104s085" }, + { .compatible = "ti,dac124s085" }, + { } +}; +MODULE_DEVICE_TABLE(of, ti_dac_of_id); +#endif + +static const struct spi_device_id ti_dac_spi_id[] = { + { "dac082s085", dual_8bit }, + { "dac102s085", dual_10bit }, + { "dac122s085", dual_12bit }, + { "dac084s085", quad_8bit }, + { "dac104s085", quad_10bit }, + { "dac124s085", quad_12bit }, + { } +}; +MODULE_DEVICE_TABLE(spi, ti_dac_spi_id); + +static struct spi_driver ti_dac_driver = { + .driver = { + .name = "ti-dac082s085", + .of_match_table = of_match_ptr(ti_dac_of_id), + }, + .probe = ti_dac_probe, + .remove = ti_dac_remove, + .id_table = ti_dac_spi_id, +}; +module_spi_driver(ti_dac_driver); + +MODULE_AUTHOR("Lukas Wunner <lukas@wunner.de>"); +MODULE_DESCRIPTION("Texas Instruments 8/10/12-bit 2/4-channel DAC driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/dac/vf610_dac.c b/drivers/iio/dac/vf610_dac.c index c4ec7779b394..5dccdd16cab3 100644 --- a/drivers/iio/dac/vf610_dac.c +++ b/drivers/iio/dac/vf610_dac.c @@ -167,7 +167,6 @@ static int vf610_write_raw(struct iio_dev *indio_dev, } static const struct iio_info vf610_dac_iio_info = { - .driver_module = THIS_MODULE, .read_raw = &vf610_read_raw, .write_raw = &vf610_write_raw, }; diff --git a/drivers/iio/dummy/Kconfig b/drivers/iio/dummy/Kconfig index aa5824d96a43..5a29fbd3c531 100644 --- a/drivers/iio/dummy/Kconfig +++ b/drivers/iio/dummy/Kconfig @@ -5,7 +5,7 @@ menu "IIO dummy driver" depends on IIO config IIO_DUMMY_EVGEN - select IRQ_WORK + select IRQ_SIM tristate config IIO_SIMPLE_DUMMY diff --git a/drivers/iio/dummy/iio_dummy_evgen.c b/drivers/iio/dummy/iio_dummy_evgen.c index 9e83f348df51..fe8884543da0 100644 --- a/drivers/iio/dummy/iio_dummy_evgen.c +++ b/drivers/iio/dummy/iio_dummy_evgen.c @@ -24,97 +24,46 @@ #include "iio_dummy_evgen.h" #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> -#include <linux/irq_work.h> +#include <linux/irq_sim.h> /* Fiddly bit of faking and irq without hardware */ #define IIO_EVENTGEN_NO 10 /** - * struct iio_dummy_handle_irq - helper struct to simulate interrupt generation - * @work: irq_work used to run handlers from hardirq context - * @irq: fake irq line number to trigger an interrupt - */ -struct iio_dummy_handle_irq { - struct irq_work work; - int irq; -}; - -/** - * struct iio_dummy_evgen - evgen state - * @chip: irq chip we are faking - * @base: base of irq range - * @enabled: mask of which irqs are enabled - * @inuse: mask of which irqs are connected * @regs: irq regs we are faking * @lock: protect the evgen state - * @handler: helper for a 'hardware-like' interrupt simulation + * @inuse: mask of which irqs are connected + * @irq_sim: interrupt simulator + * @base: base of irq range */ struct iio_dummy_eventgen { - struct irq_chip chip; - int base; - bool enabled[IIO_EVENTGEN_NO]; - bool inuse[IIO_EVENTGEN_NO]; struct iio_dummy_regs regs[IIO_EVENTGEN_NO]; struct mutex lock; - struct iio_dummy_handle_irq handler; + bool inuse[IIO_EVENTGEN_NO]; + struct irq_sim irq_sim; + int base; }; /* We can only ever have one instance of this 'device' */ static struct iio_dummy_eventgen *iio_evgen; -static const char *iio_evgen_name = "iio_dummy_evgen"; - -static void iio_dummy_event_irqmask(struct irq_data *d) -{ - struct irq_chip *chip = irq_data_get_irq_chip(d); - struct iio_dummy_eventgen *evgen = - container_of(chip, struct iio_dummy_eventgen, chip); - - evgen->enabled[d->irq - evgen->base] = false; -} - -static void iio_dummy_event_irqunmask(struct irq_data *d) -{ - struct irq_chip *chip = irq_data_get_irq_chip(d); - struct iio_dummy_eventgen *evgen = - container_of(chip, struct iio_dummy_eventgen, chip); - - evgen->enabled[d->irq - evgen->base] = true; -} - -static void iio_dummy_work_handler(struct irq_work *work) -{ - struct iio_dummy_handle_irq *irq_handler; - - irq_handler = container_of(work, struct iio_dummy_handle_irq, work); - handle_simple_irq(irq_to_desc(irq_handler->irq)); -} static int iio_dummy_evgen_create(void) { - int ret, i; + int ret; iio_evgen = kzalloc(sizeof(*iio_evgen), GFP_KERNEL); if (!iio_evgen) return -ENOMEM; - iio_evgen->base = irq_alloc_descs(-1, 0, IIO_EVENTGEN_NO, 0); - if (iio_evgen->base < 0) { - ret = iio_evgen->base; + ret = irq_sim_init(&iio_evgen->irq_sim, IIO_EVENTGEN_NO); + if (ret) { kfree(iio_evgen); return ret; } - iio_evgen->chip.name = iio_evgen_name; - iio_evgen->chip.irq_mask = &iio_dummy_event_irqmask; - iio_evgen->chip.irq_unmask = &iio_dummy_event_irqunmask; - for (i = 0; i < IIO_EVENTGEN_NO; i++) { - irq_set_chip(iio_evgen->base + i, &iio_evgen->chip); - irq_set_handler(iio_evgen->base + i, &handle_simple_irq); - irq_modify_status(iio_evgen->base + i, - IRQ_NOREQUEST | IRQ_NOAUTOEN, - IRQ_NOPROBE); - } - init_irq_work(&iio_evgen->handler.work, iio_dummy_work_handler); + + iio_evgen->base = irq_sim_irqnum(&iio_evgen->irq_sim, 0); mutex_init(&iio_evgen->lock); + return 0; } @@ -132,15 +81,17 @@ int iio_dummy_evgen_get_irq(void) return -ENODEV; mutex_lock(&iio_evgen->lock); - for (i = 0; i < IIO_EVENTGEN_NO; i++) + for (i = 0; i < IIO_EVENTGEN_NO; i++) { if (!iio_evgen->inuse[i]) { - ret = iio_evgen->base + i; + ret = irq_sim_irqnum(&iio_evgen->irq_sim, i); iio_evgen->inuse[i] = true; break; } + } mutex_unlock(&iio_evgen->lock); if (i == IIO_EVENTGEN_NO) return -ENOMEM; + return ret; } EXPORT_SYMBOL_GPL(iio_dummy_evgen_get_irq); @@ -167,7 +118,7 @@ EXPORT_SYMBOL_GPL(iio_dummy_evgen_get_regs); static void iio_dummy_evgen_free(void) { - irq_free_descs(iio_evgen->base, IIO_EVENTGEN_NO); + irq_sim_fini(&iio_evgen->irq_sim); kfree(iio_evgen); } @@ -192,9 +143,7 @@ static ssize_t iio_evgen_poke(struct device *dev, iio_evgen->regs[this_attr->address].reg_id = this_attr->address; iio_evgen->regs[this_attr->address].reg_data = event; - iio_evgen->handler.irq = iio_evgen->base + this_attr->address; - if (iio_evgen->enabled[this_attr->address]) - irq_work_queue(&iio_evgen->handler.work); + irq_sim_fire(&iio_evgen->irq_sim, this_attr->address); return len; } diff --git a/drivers/iio/dummy/iio_simple_dummy.c b/drivers/iio/dummy/iio_simple_dummy.c index ad3410e528b6..62052479c349 100644 --- a/drivers/iio/dummy/iio_simple_dummy.c +++ b/drivers/iio/dummy/iio_simple_dummy.c @@ -26,7 +26,7 @@ #include <linux/iio/sw_device.h> #include "iio_simple_dummy.h" -static struct config_item_type iio_dummy_type = { +static const struct config_item_type iio_dummy_type = { .ct_owner = THIS_MODULE, }; @@ -519,7 +519,6 @@ static int iio_dummy_write_raw(struct iio_dev *indio_dev, * Device type specific information. */ static const struct iio_info iio_dummy_info = { - .driver_module = THIS_MODULE, .read_raw = &iio_dummy_read_raw, .write_raw = &iio_dummy_write_raw, #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS diff --git a/drivers/iio/frequency/ad9523.c b/drivers/iio/frequency/ad9523.c index 99eba524f6dd..ddb6a334ae68 100644 --- a/drivers/iio/frequency/ad9523.c +++ b/drivers/iio/frequency/ad9523.c @@ -738,7 +738,6 @@ static const struct iio_info ad9523_info = { .write_raw = &ad9523_write_raw, .debugfs_reg_access = &ad9523_reg_access, .attrs = &ad9523_attribute_group, - .driver_module = THIS_MODULE, }; static int ad9523_setup(struct iio_dev *indio_dev) diff --git a/drivers/iio/frequency/adf4350.c b/drivers/iio/frequency/adf4350.c index d2d824b446f5..6d768431d90e 100644 --- a/drivers/iio/frequency/adf4350.c +++ b/drivers/iio/frequency/adf4350.c @@ -374,7 +374,6 @@ static const struct iio_chan_spec adf4350_chan = { static const struct iio_info adf4350_info = { .debugfs_reg_access = &adf4350_reg_access, - .driver_module = THIS_MODULE, }; #ifdef CONFIG_OF diff --git a/drivers/iio/gyro/adis16080.c b/drivers/iio/gyro/adis16080.c index ad31a1372a04..a551ebde4762 100644 --- a/drivers/iio/gyro/adis16080.c +++ b/drivers/iio/gyro/adis16080.c @@ -163,7 +163,6 @@ static const struct iio_chan_spec adis16080_channels[] = { static const struct iio_info adis16080_info = { .read_raw = &adis16080_read_raw, - .driver_module = THIS_MODULE, }; enum { diff --git a/drivers/iio/gyro/adis16130.c b/drivers/iio/gyro/adis16130.c index e5241f41e65e..aea80ab04122 100644 --- a/drivers/iio/gyro/adis16130.c +++ b/drivers/iio/gyro/adis16130.c @@ -137,7 +137,6 @@ static const struct iio_chan_spec adis16130_channels[] = { static const struct iio_info adis16130_info = { .read_raw = &adis16130_read_raw, - .driver_module = THIS_MODULE, }; static int adis16130_probe(struct spi_device *spi) diff --git a/drivers/iio/gyro/adis16136.c b/drivers/iio/gyro/adis16136.c index b04faf93e1bc..90ec4bed62b7 100644 --- a/drivers/iio/gyro/adis16136.c +++ b/drivers/iio/gyro/adis16136.c @@ -398,7 +398,6 @@ static const struct attribute_group adis16136_attribute_group = { }; static const struct iio_info adis16136_info = { - .driver_module = THIS_MODULE, .attrs = &adis16136_attribute_group, .read_raw = &adis16136_read_raw, .write_raw = &adis16136_write_raw, diff --git a/drivers/iio/gyro/adis16260.c b/drivers/iio/gyro/adis16260.c index 7da8825f4791..a8cb1ca349d9 100644 --- a/drivers/iio/gyro/adis16260.c +++ b/drivers/iio/gyro/adis16260.c @@ -321,7 +321,6 @@ static const struct iio_info adis16260_info = { .read_raw = &adis16260_read_raw, .write_raw = &adis16260_write_raw, .update_scan_mode = adis_update_scan_mode, - .driver_module = THIS_MODULE, }; static const char * const adis1620_status_error_msgs[] = { diff --git a/drivers/iio/gyro/adxrs450.c b/drivers/iio/gyro/adxrs450.c index a330d4288bb0..5d39fd008378 100644 --- a/drivers/iio/gyro/adxrs450.c +++ b/drivers/iio/gyro/adxrs450.c @@ -405,7 +405,6 @@ static const struct iio_chan_spec adxrs450_channels[2][2] = { }; static const struct iio_info adxrs450_info = { - .driver_module = THIS_MODULE, .read_raw = &adxrs450_read_raw, .write_raw = &adxrs450_write_raw, }; diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c index 821919dd245b..15046172e437 100644 --- a/drivers/iio/gyro/bmg160_core.c +++ b/drivers/iio/gyro/bmg160_core.c @@ -858,7 +858,6 @@ static const struct iio_info bmg160_info = { .write_event_value = bmg160_write_event, .write_event_config = bmg160_write_event_config, .read_event_config = bmg160_read_event_config, - .driver_module = THIS_MODULE, }; static const unsigned long bmg160_accel_scan_masks[] = { @@ -956,7 +955,6 @@ static int bmg160_data_rdy_trigger_set_state(struct iio_trigger *trig, static const struct iio_trigger_ops bmg160_trigger_ops = { .set_trigger_state = bmg160_data_rdy_trigger_set_state, .try_reenable = bmg160_trig_try_reen, - .owner = THIS_MODULE, }; static irqreturn_t bmg160_event_handler(int irq, void *private) diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c index c67ce2ac4715..f59995a90387 100644 --- a/drivers/iio/gyro/hid-sensor-gyro-3d.c +++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c @@ -186,7 +186,6 @@ static int gyro_3d_write_raw(struct iio_dev *indio_dev, } static const struct iio_info gyro_3d_info = { - .driver_module = THIS_MODULE, .read_raw = &gyro_3d_read_raw, .write_raw = &gyro_3d_write_raw, }; diff --git a/drivers/iio/gyro/itg3200_buffer.c b/drivers/iio/gyro/itg3200_buffer.c index eef50e91f17c..59770e5b6660 100644 --- a/drivers/iio/gyro/itg3200_buffer.c +++ b/drivers/iio/gyro/itg3200_buffer.c @@ -101,7 +101,6 @@ error_ret: } static const struct iio_trigger_ops itg3200_trigger_ops = { - .owner = THIS_MODULE, .set_trigger_state = &itg3200_data_rdy_trigger_set_state, }; diff --git a/drivers/iio/gyro/itg3200_core.c b/drivers/iio/gyro/itg3200_core.c index cfa2db04a8ab..7adecb562c81 100644 --- a/drivers/iio/gyro/itg3200_core.c +++ b/drivers/iio/gyro/itg3200_core.c @@ -278,7 +278,6 @@ static const struct iio_chan_spec itg3200_channels[] = { static const struct iio_info itg3200_info = { .read_raw = &itg3200_read_raw, .write_raw = &itg3200_write_raw, - .driver_module = THIS_MODULE, }; static const unsigned long itg3200_available_scan_masks[] = { 0xffffffff, 0x0 }; diff --git a/drivers/iio/gyro/mpu3050-core.c b/drivers/iio/gyro/mpu3050-core.c index e0d241a9aa30..77fac81a3adc 100644 --- a/drivers/iio/gyro/mpu3050-core.c +++ b/drivers/iio/gyro/mpu3050-core.c @@ -742,7 +742,6 @@ static const struct attribute_group mpu3050_attribute_group = { }; static const struct iio_info mpu3050_info = { - .driver_module = THIS_MODULE, .read_raw = mpu3050_read_raw, .write_raw = mpu3050_write_raw, .attrs = &mpu3050_attribute_group, @@ -1032,7 +1031,6 @@ static int mpu3050_drdy_trigger_set_state(struct iio_trigger *trig, } static const struct iio_trigger_ops mpu3050_trigger_ops = { - .owner = THIS_MODULE, .set_trigger_state = mpu3050_drdy_trigger_set_state, }; diff --git a/drivers/iio/gyro/st_gyro_core.c b/drivers/iio/gyro/st_gyro_core.c index e366422e8512..b31064ba37b9 100644 --- a/drivers/iio/gyro/st_gyro_core.c +++ b/drivers/iio/gyro/st_gyro_core.c @@ -111,14 +111,23 @@ static const struct st_sensor_settings st_gyro_sensors_settings[] = { .mask = 0x80, }, .drdy_irq = { - .addr = 0x22, - .mask_int2 = 0x08, + .int2 = { + .addr = 0x22, + .mask = 0x08, + }, /* * The sensor has IHL (active low) and open * drain settings, but only for INT1 and not * for the DRDY line on INT2. */ - .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR, + .stat_drdy = { + .addr = ST_SENSORS_DEFAULT_STAT_ADDR, + .mask = 0x07, + }, + }, + .sim = { + .addr = 0x23, + .value = BIT(0), }, .multi_read_bit = true, .bootime = 2, @@ -181,14 +190,23 @@ static const struct st_sensor_settings st_gyro_sensors_settings[] = { .mask = 0x80, }, .drdy_irq = { - .addr = 0x22, - .mask_int2 = 0x08, + .int2 = { + .addr = 0x22, + .mask = 0x08, + }, /* * The sensor has IHL (active low) and open * drain settings, but only for INT1 and not * for the DRDY line on INT2. */ - .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR, + .stat_drdy = { + .addr = ST_SENSORS_DEFAULT_STAT_ADDR, + .mask = 0x07, + }, + }, + .sim = { + .addr = 0x23, + .value = BIT(0), }, .multi_read_bit = true, .bootime = 2, @@ -246,14 +264,23 @@ static const struct st_sensor_settings st_gyro_sensors_settings[] = { .mask = 0x80, }, .drdy_irq = { - .addr = 0x22, - .mask_int2 = 0x08, + .int2 = { + .addr = 0x22, + .mask = 0x08, + }, /* * The sensor has IHL (active low) and open * drain settings, but only for INT1 and not * for the DRDY line on INT2. */ - .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR, + .stat_drdy = { + .addr = ST_SENSORS_DEFAULT_STAT_ADDR, + .mask = 0x07, + }, + }, + .sim = { + .addr = 0x23, + .value = BIT(0), }, .multi_read_bit = true, .bootime = 2, @@ -326,7 +353,6 @@ static const struct attribute_group st_gyro_attribute_group = { }; static const struct iio_info gyro_info = { - .driver_module = THIS_MODULE, .attrs = &st_gyro_attribute_group, .read_raw = &st_gyro_read_raw, .write_raw = &st_gyro_write_raw, @@ -335,7 +361,6 @@ static const struct iio_info gyro_info = { #ifdef CONFIG_IIO_TRIGGER static const struct iio_trigger_ops st_gyro_trigger_ops = { - .owner = THIS_MODULE, .set_trigger_state = ST_GYRO_TRIGGER_SET_STATE, .validate_device = st_sensors_validate_device, }; diff --git a/drivers/iio/health/afe4403.c b/drivers/iio/health/afe4403.c index 6bb23a49e81e..a739fff01c6b 100644 --- a/drivers/iio/health/afe4403.c +++ b/drivers/iio/health/afe4403.c @@ -309,7 +309,6 @@ static const struct iio_info afe4403_iio_info = { .attrs = &afe440x_attribute_group, .read_raw = afe4403_read_raw, .write_raw = afe4403_write_raw, - .driver_module = THIS_MODULE, }; static irqreturn_t afe4403_trigger_handler(int irq, void *private) @@ -354,7 +353,6 @@ err: } static const struct iio_trigger_ops afe4403_trigger_ops = { - .owner = THIS_MODULE, }; #define AFE4403_TIMING_PAIRS \ diff --git a/drivers/iio/health/afe4404.c b/drivers/iio/health/afe4404.c index 964f5231a831..11910922e655 100644 --- a/drivers/iio/health/afe4404.c +++ b/drivers/iio/health/afe4404.c @@ -328,7 +328,6 @@ static const struct iio_info afe4404_iio_info = { .attrs = &afe440x_attribute_group, .read_raw = afe4404_read_raw, .write_raw = afe4404_write_raw, - .driver_module = THIS_MODULE, }; static irqreturn_t afe4404_trigger_handler(int irq, void *private) @@ -355,7 +354,6 @@ err: } static const struct iio_trigger_ops afe4404_trigger_ops = { - .owner = THIS_MODULE, }; /* Default timings from data-sheet */ diff --git a/drivers/iio/health/max30100.c b/drivers/iio/health/max30100.c index 849d71747f9f..91aef5df24a1 100644 --- a/drivers/iio/health/max30100.c +++ b/drivers/iio/health/max30100.c @@ -420,7 +420,6 @@ static int max30100_read_raw(struct iio_dev *indio_dev, } static const struct iio_info max30100_info = { - .driver_module = THIS_MODULE, .read_raw = max30100_read_raw, }; diff --git a/drivers/iio/health/max30102.c b/drivers/iio/health/max30102.c index 839b875c29b9..203ffb9cad6a 100644 --- a/drivers/iio/health/max30102.c +++ b/drivers/iio/health/max30102.c @@ -381,7 +381,6 @@ static int max30102_read_raw(struct iio_dev *indio_dev, } static const struct iio_info max30102_info = { - .driver_module = THIS_MODULE, .read_raw = max30102_read_raw, }; diff --git a/drivers/iio/humidity/am2315.c b/drivers/iio/humidity/am2315.c index ff96b6d0fdae..7d8669dc6547 100644 --- a/drivers/iio/humidity/am2315.c +++ b/drivers/iio/humidity/am2315.c @@ -215,7 +215,6 @@ static int am2315_read_raw(struct iio_dev *indio_dev, } static const struct iio_info am2315_info = { - .driver_module = THIS_MODULE, .read_raw = am2315_read_raw, }; diff --git a/drivers/iio/humidity/dht11.c b/drivers/iio/humidity/dht11.c index 2a22ad920333..df6bab40d6fa 100644 --- a/drivers/iio/humidity/dht11.c +++ b/drivers/iio/humidity/dht11.c @@ -284,7 +284,6 @@ err: } static const struct iio_info dht11_iio_info = { - .driver_module = THIS_MODULE, .read_raw = dht11_read_raw, }; diff --git a/drivers/iio/humidity/hdc100x.c b/drivers/iio/humidity/hdc100x.c index 7851bd90ef64..d8438310b6d4 100644 --- a/drivers/iio/humidity/hdc100x.c +++ b/drivers/iio/humidity/hdc100x.c @@ -357,7 +357,6 @@ static const struct iio_info hdc100x_info = { .read_raw = hdc100x_read_raw, .write_raw = hdc100x_write_raw, .attrs = &hdc100x_attribute_group, - .driver_module = THIS_MODULE, }; static int hdc100x_probe(struct i2c_client *client, diff --git a/drivers/iio/humidity/hid-sensor-humidity.c b/drivers/iio/humidity/hid-sensor-humidity.c index 6e09c1acfe51..beab6d6fd6e1 100644 --- a/drivers/iio/humidity/hid-sensor-humidity.c +++ b/drivers/iio/humidity/hid-sensor-humidity.c @@ -125,7 +125,6 @@ static int humidity_write_raw(struct iio_dev *indio_dev, } static const struct iio_info humidity_info = { - .driver_module = THIS_MODULE, .read_raw = &humidity_read_raw, .write_raw = &humidity_write_raw, }; diff --git a/drivers/iio/humidity/hts221_buffer.c b/drivers/iio/humidity/hts221_buffer.c index 9690dfe9a844..e971ea425268 100644 --- a/drivers/iio/humidity/hts221_buffer.c +++ b/drivers/iio/humidity/hts221_buffer.c @@ -47,7 +47,6 @@ static int hts221_trig_set_state(struct iio_trigger *trig, bool state) } static const struct iio_trigger_ops hts221_trigger_ops = { - .owner = THIS_MODULE, .set_trigger_state = hts221_trig_set_state, }; diff --git a/drivers/iio/humidity/hts221_core.c b/drivers/iio/humidity/hts221_core.c index 32524a8dc66f..daef177219b6 100644 --- a/drivers/iio/humidity/hts221_core.c +++ b/drivers/iio/humidity/hts221_core.c @@ -573,7 +573,6 @@ static const struct attribute_group hts221_attribute_group = { }; static const struct iio_info hts221_info = { - .driver_module = THIS_MODULE, .attrs = &hts221_attribute_group, .read_raw = hts221_read_raw, .write_raw = hts221_write_raw, diff --git a/drivers/iio/humidity/htu21.c b/drivers/iio/humidity/htu21.c index 2c4b9be85a05..f5a2701ba6dd 100644 --- a/drivers/iio/humidity/htu21.c +++ b/drivers/iio/humidity/htu21.c @@ -175,7 +175,6 @@ static const struct iio_info htu21_info = { .read_raw = htu21_read_raw, .write_raw = htu21_write_raw, .attrs = &htu21_attribute_group, - .driver_module = THIS_MODULE, }; static int htu21_probe(struct i2c_client *client, diff --git a/drivers/iio/humidity/si7005.c b/drivers/iio/humidity/si7005.c index 6297766e93d0..1fd19f035a5d 100644 --- a/drivers/iio/humidity/si7005.c +++ b/drivers/iio/humidity/si7005.c @@ -124,7 +124,6 @@ static const struct iio_chan_spec si7005_channels[] = { static const struct iio_info si7005_info = { .read_raw = si7005_read_raw, - .driver_module = THIS_MODULE, }; static int si7005_probe(struct i2c_client *client, diff --git a/drivers/iio/humidity/si7020.c b/drivers/iio/humidity/si7020.c index 345a7656c5ef..1b2ec8df1a72 100644 --- a/drivers/iio/humidity/si7020.c +++ b/drivers/iio/humidity/si7020.c @@ -108,7 +108,6 @@ static const struct iio_chan_spec si7020_channels[] = { static const struct iio_info si7020_info = { .read_raw = si7020_read_raw, - .driver_module = THIS_MODULE, }; static int si7020_probe(struct i2c_client *client, diff --git a/drivers/iio/imu/adis16400_core.c b/drivers/iio/imu/adis16400_core.c index 9b697d35dbef..46a569005a13 100644 --- a/drivers/iio/imu/adis16400_core.c +++ b/drivers/iio/imu/adis16400_core.c @@ -833,7 +833,6 @@ static struct adis16400_chip_info adis16400_chips[] = { }; static const struct iio_info adis16400_info = { - .driver_module = THIS_MODULE, .read_raw = &adis16400_read_raw, .write_raw = &adis16400_write_raw, .update_scan_mode = adis16400_update_scan_mode, diff --git a/drivers/iio/imu/adis16480.c b/drivers/iio/imu/adis16480.c index 12898424d838..7a33d6bd60e0 100644 --- a/drivers/iio/imu/adis16480.c +++ b/drivers/iio/imu/adis16480.c @@ -720,7 +720,6 @@ static const struct iio_info adis16480_info = { .read_raw = &adis16480_read_raw, .write_raw = &adis16480_write_raw, .update_scan_mode = adis_update_scan_mode, - .driver_module = THIS_MODULE, }; static int adis16480_stop_device(struct iio_dev *indio_dev) diff --git a/drivers/iio/imu/adis_trigger.c b/drivers/iio/imu/adis_trigger.c index f53e9a803a0e..0dd5a381be64 100644 --- a/drivers/iio/imu/adis_trigger.c +++ b/drivers/iio/imu/adis_trigger.c @@ -25,7 +25,6 @@ static int adis_data_rdy_trigger_set_state(struct iio_trigger *trig, } static const struct iio_trigger_ops adis_trigger_ops = { - .owner = THIS_MODULE, .set_trigger_state = &adis_data_rdy_trigger_set_state, }; diff --git a/drivers/iio/imu/bmi160/bmi160_core.c b/drivers/iio/imu/bmi160/bmi160_core.c index cfd225ed1c8d..c85659ca9507 100644 --- a/drivers/iio/imu/bmi160/bmi160_core.c +++ b/drivers/iio/imu/bmi160/bmi160_core.c @@ -482,7 +482,6 @@ static const struct attribute_group bmi160_attrs_group = { }; static const struct iio_info bmi160_info = { - .driver_module = THIS_MODULE, .read_raw = bmi160_read_raw, .write_raw = bmi160_write_raw, .attrs = &bmi160_attrs_group, diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index 44830bce13df..7d64be353403 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -542,7 +542,9 @@ static int inv_mpu6050_write_raw(struct iio_dev *indio_dev, break; default: result = -EINVAL; + break; } + break; default: result = -EINVAL; break; @@ -570,10 +572,12 @@ error_write_raw_unlock: */ static int inv_mpu6050_set_lpf(struct inv_mpu6050_state *st, int rate) { - const int hz[] = {188, 98, 42, 20, 10, 5}; - const int d[] = {INV_MPU6050_FILTER_188HZ, INV_MPU6050_FILTER_98HZ, - INV_MPU6050_FILTER_42HZ, INV_MPU6050_FILTER_20HZ, - INV_MPU6050_FILTER_10HZ, INV_MPU6050_FILTER_5HZ}; + static const int hz[] = {188, 98, 42, 20, 10, 5}; + static const int d[] = { + INV_MPU6050_FILTER_188HZ, INV_MPU6050_FILTER_98HZ, + INV_MPU6050_FILTER_42HZ, INV_MPU6050_FILTER_20HZ, + INV_MPU6050_FILTER_10HZ, INV_MPU6050_FILTER_5HZ + }; int i, h, result; u8 data; @@ -795,7 +799,6 @@ static const struct attribute_group inv_attribute_group = { }; static const struct iio_info mpu_info = { - .driver_module = THIS_MODULE, .read_raw = &inv_mpu6050_read_raw, .write_raw = &inv_mpu6050_write_raw, .write_raw_get_fmt = &inv_write_raw_get_fmt, diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c index 540070f0a230..f963f9fc98c0 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c @@ -114,7 +114,6 @@ static int inv_mpu_data_rdy_trigger_set_state(struct iio_trigger *trig, } static const struct iio_trigger_ops inv_mpu_trigger_ops = { - .owner = THIS_MODULE, .set_trigger_state = &inv_mpu_data_rdy_trigger_set_state, }; diff --git a/drivers/iio/imu/kmx61.c b/drivers/iio/imu/kmx61.c index 2e7dd5754a56..44b3f5397343 100644 --- a/drivers/iio/imu/kmx61.c +++ b/drivers/iio/imu/kmx61.c @@ -1003,7 +1003,6 @@ static int kmx61_mag_validate_trigger(struct iio_dev *indio_dev, } static const struct iio_info kmx61_acc_info = { - .driver_module = THIS_MODULE, .read_raw = kmx61_read_raw, .write_raw = kmx61_write_raw, .attrs = &kmx61_acc_attribute_group, @@ -1015,7 +1014,6 @@ static const struct iio_info kmx61_acc_info = { }; static const struct iio_info kmx61_mag_info = { - .driver_module = THIS_MODULE, .read_raw = kmx61_read_raw, .write_raw = kmx61_write_raw, .attrs = &kmx61_mag_attribute_group, @@ -1087,7 +1085,6 @@ static int kmx61_trig_try_reenable(struct iio_trigger *trig) static const struct iio_trigger_ops kmx61_trigger_ops = { .set_trigger_state = kmx61_data_rdy_trigger_set_state, .try_reenable = kmx61_trig_try_reenable, - .owner = THIS_MODULE, }; static irqreturn_t kmx61_event_handler(int irq, void *private) diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h index 46352c7bff43..4fdb7fcc3ea8 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -29,8 +29,6 @@ enum st_lsm6dsx_hw_id { #define ST_LSM6DSX_CHAN_SIZE 2 #define ST_LSM6DSX_SAMPLE_SIZE 6 -#define ST_LSM6DSX_SAMPLE_DEPTH (ST_LSM6DSX_SAMPLE_SIZE / \ - ST_LSM6DSX_CHAN_SIZE) #if defined(CONFIG_SPI_MASTER) #define ST_LSM6DSX_RX_MAX_LENGTH 256 @@ -52,10 +50,38 @@ struct st_lsm6dsx_reg { u8 mask; }; +/** + * struct st_lsm6dsx_fifo_ops - ST IMU FIFO settings + * @fifo_th: FIFO threshold register info (addr + mask). + * @fifo_diff: FIFO diff status register info (addr + mask). + * @th_wl: FIFO threshold word length. + */ +struct st_lsm6dsx_fifo_ops { + struct { + u8 addr; + u16 mask; + } fifo_th; + struct { + u8 addr; + u16 mask; + } fifo_diff; + u8 th_wl; +}; + +/** + * struct st_lsm6dsx_settings - ST IMU sensor settings + * @wai: Sensor WhoAmI default value. + * @max_fifo_size: Sensor max fifo length in FIFO words. + * @id: List of hw id supported by the driver configuration. + * @decimator: List of decimator register info (addr + mask). + * @fifo_ops: Sensor hw FIFO parameters. + */ struct st_lsm6dsx_settings { u8 wai; u16 max_fifo_size; enum st_lsm6dsx_hw_id id[ST_LSM6DSX_MAX_ID]; + struct st_lsm6dsx_reg decimator[ST_LSM6DSX_MAX_ID]; + struct st_lsm6dsx_fifo_ops fifo_ops; }; enum st_lsm6dsx_sensor_id { @@ -79,7 +105,6 @@ enum st_lsm6dsx_fifo_mode { * @watermark: Sensor watermark level. * @sip: Number of samples in a given pattern. * @decimator: FIFO decimation factor. - * @decimator_mask: Sensor mask for decimation register. * @delta_ts: Delta time between two consecutive interrupts. * @ts: Latest timestamp from the interrupt handler. */ @@ -94,7 +119,6 @@ struct st_lsm6dsx_sensor { u16 watermark; u8 sip; u8 decimator; - u8 decimator_mask; s64 delta_ts; s64 ts; diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c index e2737dc71b67..755c472e8a05 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c @@ -35,10 +35,6 @@ #include "st_lsm6dsx.h" -#define ST_LSM6DSX_REG_FIFO_THL_ADDR 0x06 -#define ST_LSM6DSX_REG_FIFO_THH_ADDR 0x07 -#define ST_LSM6DSX_FIFO_TH_MASK GENMASK(11, 0) -#define ST_LSM6DSX_REG_FIFO_DEC_GXL_ADDR 0x08 #define ST_LSM6DSX_REG_HLACTIVE_ADDR 0x12 #define ST_LSM6DSX_REG_HLACTIVE_MASK BIT(5) #define ST_LSM6DSX_REG_PP_OD_ADDR 0x12 @@ -46,8 +42,6 @@ #define ST_LSM6DSX_REG_FIFO_MODE_ADDR 0x0a #define ST_LSM6DSX_FIFO_MODE_MASK GENMASK(2, 0) #define ST_LSM6DSX_FIFO_ODR_MASK GENMASK(6, 3) -#define ST_LSM6DSX_REG_FIFO_DIFFL_ADDR 0x3a -#define ST_LSM6DSX_FIFO_DIFF_MASK GENMASK(11, 0) #define ST_LSM6DSX_FIFO_EMPTY_MASK BIT(12) #define ST_LSM6DSX_REG_FIFO_OUTL_ADDR 0x3e @@ -110,8 +104,9 @@ static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw) st_lsm6dsx_get_max_min_odr(hw, &max_odr, &min_odr); for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { - sensor = iio_priv(hw->iio_devs[i]); + const struct st_lsm6dsx_reg *dec_reg; + sensor = iio_priv(hw->iio_devs[i]); /* update fifo decimators and sample in pattern */ if (hw->enable_mask & BIT(sensor->id)) { sensor->sip = sensor->odr / min_odr; @@ -123,12 +118,13 @@ static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw) data = 0; } - err = st_lsm6dsx_write_with_mask(hw, - ST_LSM6DSX_REG_FIFO_DEC_GXL_ADDR, - sensor->decimator_mask, data); - if (err < 0) - return err; - + dec_reg = &hw->settings->decimator[sensor->id]; + if (dec_reg->addr) { + err = st_lsm6dsx_write_with_mask(hw, dec_reg->addr, + dec_reg->mask, data); + if (err < 0) + return err; + } sip += sensor->sip; } hw->sip = sip; @@ -139,23 +135,10 @@ static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw) int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw, enum st_lsm6dsx_fifo_mode fifo_mode) { - u8 data; int err; - switch (fifo_mode) { - case ST_LSM6DSX_FIFO_BYPASS: - data = fifo_mode; - break; - case ST_LSM6DSX_FIFO_CONT: - data = (ST_LSM6DSX_MAX_FIFO_ODR_VAL << - __ffs(ST_LSM6DSX_FIFO_ODR_MASK)) | fifo_mode; - break; - default: - return -EINVAL; - } - - err = hw->tf->write(hw->dev, ST_LSM6DSX_REG_FIFO_MODE_ADDR, - sizeof(data), &data); + err = st_lsm6dsx_write_with_mask(hw, ST_LSM6DSX_REG_FIFO_MODE_ADDR, + ST_LSM6DSX_FIFO_MODE_MASK, fifo_mode); if (err < 0) return err; @@ -164,9 +147,20 @@ int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw, return 0; } +static int st_lsm6dsx_set_fifo_odr(struct st_lsm6dsx_sensor *sensor, + bool enable) +{ + struct st_lsm6dsx_hw *hw = sensor->hw; + u8 data; + + data = hw->enable_mask ? ST_LSM6DSX_MAX_FIFO_ODR_VAL : 0; + return st_lsm6dsx_write_with_mask(hw, ST_LSM6DSX_REG_FIFO_MODE_ADDR, + ST_LSM6DSX_FIFO_ODR_MASK, data); +} + int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor, u16 watermark) { - u16 fifo_watermark = ~0, cur_watermark, sip = 0; + u16 fifo_watermark = ~0, cur_watermark, sip = 0, fifo_th_mask; struct st_lsm6dsx_hw *hw = sensor->hw; struct st_lsm6dsx_sensor *cur_sensor; __le16 wdata; @@ -191,20 +185,21 @@ int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor, u16 watermark) fifo_watermark = max_t(u16, fifo_watermark, sip); fifo_watermark = (fifo_watermark / sip) * sip; - fifo_watermark = fifo_watermark * ST_LSM6DSX_SAMPLE_DEPTH; + fifo_watermark = fifo_watermark * hw->settings->fifo_ops.th_wl; mutex_lock(&hw->lock); - err = hw->tf->read(hw->dev, ST_LSM6DSX_REG_FIFO_THH_ADDR, + err = hw->tf->read(hw->dev, hw->settings->fifo_ops.fifo_th.addr + 1, sizeof(data), &data); if (err < 0) goto out; - fifo_watermark = ((data << 8) & ~ST_LSM6DSX_FIFO_TH_MASK) | - (fifo_watermark & ST_LSM6DSX_FIFO_TH_MASK); + fifo_th_mask = hw->settings->fifo_ops.fifo_th.mask; + fifo_watermark = ((data << 8) & ~fifo_th_mask) | + (fifo_watermark & fifo_th_mask); wdata = cpu_to_le16(fifo_watermark); - err = hw->tf->write(hw->dev, ST_LSM6DSX_REG_FIFO_THL_ADDR, + err = hw->tf->write(hw->dev, hw->settings->fifo_ops.fifo_th.addr, sizeof(wdata), (u8 *)&wdata); out: mutex_unlock(&hw->lock); @@ -223,6 +218,7 @@ out: static int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) { u16 fifo_len, pattern_len = hw->sip * ST_LSM6DSX_SAMPLE_SIZE; + u16 fifo_diff_mask = hw->settings->fifo_ops.fifo_diff.mask; int err, acc_sip, gyro_sip, read_len, samples, offset; struct st_lsm6dsx_sensor *acc_sensor, *gyro_sensor; s64 acc_ts, acc_delta_ts, gyro_ts, gyro_delta_ts; @@ -230,7 +226,7 @@ static int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) u8 buff[pattern_len]; __le16 fifo_status; - err = hw->tf->read(hw->dev, ST_LSM6DSX_REG_FIFO_DIFFL_ADDR, + err = hw->tf->read(hw->dev, hw->settings->fifo_ops.fifo_diff.addr, sizeof(fifo_status), (u8 *)&fifo_status); if (err < 0) return err; @@ -238,7 +234,7 @@ static int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) if (fifo_status & cpu_to_le16(ST_LSM6DSX_FIFO_EMPTY_MASK)) return 0; - fifo_len = (le16_to_cpu(fifo_status) & ST_LSM6DSX_FIFO_DIFF_MASK) * + fifo_len = (le16_to_cpu(fifo_status) & fifo_diff_mask) * ST_LSM6DSX_CHAN_SIZE; samples = fifo_len / ST_LSM6DSX_SAMPLE_SIZE; fifo_len = (fifo_len / pattern_len) * pattern_len; @@ -345,6 +341,10 @@ static int st_lsm6dsx_update_fifo(struct iio_dev *iio_dev, bool enable) return err; } + err = st_lsm6dsx_set_fifo_odr(sensor, enable); + if (err < 0) + return err; + err = st_lsm6dsx_update_decimators(hw); if (err < 0) return err; diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index b485540da89e..239c735242be 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -42,8 +42,6 @@ #include "st_lsm6dsx.h" -#define ST_LSM6DSX_REG_ACC_DEC_MASK GENMASK(2, 0) -#define ST_LSM6DSX_REG_GYRO_DEC_MASK GENMASK(5, 3) #define ST_LSM6DSX_REG_INT1_ADDR 0x0d #define ST_LSM6DSX_REG_INT2_ADDR 0x0e #define ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK BIT(3) @@ -54,10 +52,6 @@ #define ST_LSM6DSX_REG_BDU_MASK BIT(6) #define ST_LSM6DSX_REG_INT2_ON_INT1_ADDR 0x13 #define ST_LSM6DSX_REG_INT2_ON_INT1_MASK BIT(5) -#define ST_LSM6DSX_REG_ROUNDING_ADDR 0x16 -#define ST_LSM6DSX_REG_ROUNDING_MASK BIT(2) -#define ST_LSM6DSX_REG_LIR_ADDR 0x58 -#define ST_LSM6DSX_REG_LIR_MASK BIT(0) #define ST_LSM6DSX_REG_ACC_ODR_ADDR 0x10 #define ST_LSM6DSX_REG_ACC_ODR_MASK GENMASK(7, 4) @@ -160,25 +154,88 @@ static const struct st_lsm6dsx_fs_table_entry st_lsm6dsx_fs_table[] = { static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { { .wai = 0x69, - .max_fifo_size = 8192, + .max_fifo_size = 1365, .id = { [0] = ST_LSM6DS3_ID, }, + .decimator = { + [ST_LSM6DSX_ID_ACC] = { + .addr = 0x08, + .mask = GENMASK(2, 0), + }, + [ST_LSM6DSX_ID_GYRO] = { + .addr = 0x08, + .mask = GENMASK(5, 3), + }, + }, + .fifo_ops = { + .fifo_th = { + .addr = 0x06, + .mask = GENMASK(11, 0), + }, + .fifo_diff = { + .addr = 0x3a, + .mask = GENMASK(11, 0), + }, + .th_wl = 3, /* 1LSB = 2B */ + }, }, { .wai = 0x69, - .max_fifo_size = 4096, + .max_fifo_size = 682, .id = { [0] = ST_LSM6DS3H_ID, }, + .decimator = { + [ST_LSM6DSX_ID_ACC] = { + .addr = 0x08, + .mask = GENMASK(2, 0), + }, + [ST_LSM6DSX_ID_GYRO] = { + .addr = 0x08, + .mask = GENMASK(5, 3), + }, + }, + .fifo_ops = { + .fifo_th = { + .addr = 0x06, + .mask = GENMASK(11, 0), + }, + .fifo_diff = { + .addr = 0x3a, + .mask = GENMASK(11, 0), + }, + .th_wl = 3, /* 1LSB = 2B */ + }, }, { .wai = 0x6a, - .max_fifo_size = 4096, + .max_fifo_size = 682, .id = { [0] = ST_LSM6DSL_ID, [1] = ST_LSM6DSM_ID, }, + .decimator = { + [ST_LSM6DSX_ID_ACC] = { + .addr = 0x08, + .mask = GENMASK(2, 0), + }, + [ST_LSM6DSX_ID_GYRO] = { + .addr = 0x08, + .mask = GENMASK(5, 3), + }, + }, + .fifo_ops = { + .fifo_th = { + .addr = 0x06, + .mask = GENMASK(11, 0), + }, + .fifo_diff = { + .addr = 0x3a, + .mask = GENMASK(11, 0), + }, + .th_wl = 3, /* 1LSB = 2B */ + }, }, }; @@ -322,7 +379,6 @@ static int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u16 odr, return -EINVAL; *val = st_lsm6dsx_odr_table[sensor->id].odr_avl[i].val; - sensor->odr = odr; return 0; } @@ -449,6 +505,8 @@ static int st_lsm6dsx_write_raw(struct iio_dev *iio_dev, u8 data; err = st_lsm6dsx_check_odr(sensor, val, &data); + if (!err) + sensor->odr = val; break; } default: @@ -465,10 +523,9 @@ static int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val) { struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); struct st_lsm6dsx_hw *hw = sensor->hw; - int err, max_fifo_len; + int err; - max_fifo_len = hw->settings->max_fifo_size / ST_LSM6DSX_SAMPLE_SIZE; - if (val < 1 || val > max_fifo_len) + if (val < 1 || val > hw->settings->max_fifo_size) return -EINVAL; err = st_lsm6dsx_update_watermark(sensor, val); @@ -530,7 +587,6 @@ static const struct attribute_group st_lsm6dsx_acc_attribute_group = { }; static const struct iio_info st_lsm6dsx_acc_info = { - .driver_module = THIS_MODULE, .attrs = &st_lsm6dsx_acc_attribute_group, .read_raw = st_lsm6dsx_read_raw, .write_raw = st_lsm6dsx_write_raw, @@ -548,7 +604,6 @@ static const struct attribute_group st_lsm6dsx_gyro_attribute_group = { }; static const struct iio_info st_lsm6dsx_gyro_info = { - .driver_module = THIS_MODULE, .attrs = &st_lsm6dsx_gyro_attribute_group, .read_raw = st_lsm6dsx_read_raw, .write_raw = st_lsm6dsx_write_raw, @@ -608,23 +663,12 @@ static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw) msleep(200); - /* latch interrupts */ - err = st_lsm6dsx_write_with_mask(hw, ST_LSM6DSX_REG_LIR_ADDR, - ST_LSM6DSX_REG_LIR_MASK, 1); - if (err < 0) - return err; - /* enable Block Data Update */ err = st_lsm6dsx_write_with_mask(hw, ST_LSM6DSX_REG_BDU_ADDR, ST_LSM6DSX_REG_BDU_MASK, 1); if (err < 0) return err; - err = st_lsm6dsx_write_with_mask(hw, ST_LSM6DSX_REG_ROUNDING_ADDR, - ST_LSM6DSX_REG_ROUNDING_MASK, 1); - if (err < 0) - return err; - /* enable FIFO watermak interrupt */ err = st_lsm6dsx_get_drdy_reg(hw, &drdy_int_reg); if (err < 0) @@ -662,7 +706,6 @@ static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw, iio_dev->num_channels = ARRAY_SIZE(st_lsm6dsx_acc_channels); iio_dev->info = &st_lsm6dsx_acc_info; - sensor->decimator_mask = ST_LSM6DSX_REG_ACC_DEC_MASK; scnprintf(sensor->name, sizeof(sensor->name), "%s_accel", name); break; @@ -671,7 +714,6 @@ static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw, iio_dev->num_channels = ARRAY_SIZE(st_lsm6dsx_gyro_channels); iio_dev->info = &st_lsm6dsx_gyro_info; - sensor->decimator_mask = ST_LSM6DSX_REG_GYRO_DEC_MASK; scnprintf(sensor->name, sizeof(sensor->name), "%s_gyro", name); break; diff --git a/drivers/iio/industrialio-configfs.c b/drivers/iio/industrialio-configfs.c index 45ce2bc47180..5a0aae119369 100644 --- a/drivers/iio/industrialio-configfs.c +++ b/drivers/iio/industrialio-configfs.c @@ -17,7 +17,7 @@ #include <linux/iio/iio.h> #include <linux/iio/configfs.h> -static struct config_item_type iio_root_group_type = { +static const struct config_item_type iio_root_group_type = { .ct_owner = THIS_MODULE, }; diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index a47428b4d31b..9c4cfd19b739 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -1662,14 +1662,11 @@ static int iio_check_unique_scan_index(struct iio_dev *indio_dev) static const struct iio_buffer_setup_ops noop_ring_setup_ops; -/** - * iio_device_register() - register a device with the IIO subsystem - * @indio_dev: Device structure filled by the device driver - **/ -int iio_device_register(struct iio_dev *indio_dev) +int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod) { int ret; + indio_dev->driver_module = this_mod; /* If the calling driver did not initialize of_node, do it here */ if (!indio_dev->dev.of_node && indio_dev->dev.parent) indio_dev->dev.of_node = indio_dev->dev.parent->of_node; @@ -1715,7 +1712,8 @@ int iio_device_register(struct iio_dev *indio_dev) indio_dev->setup_ops = &noop_ring_setup_ops; cdev_init(&indio_dev->chrdev, &iio_buffer_fileops); - indio_dev->chrdev.owner = indio_dev->info->driver_module; + + indio_dev->chrdev.owner = this_mod; ret = cdev_device_add(&indio_dev->chrdev, &indio_dev->dev); if (ret < 0) @@ -1733,7 +1731,7 @@ error_unreg_debugfs: iio_device_unregister_debugfs(indio_dev); return ret; } -EXPORT_SYMBOL(iio_device_register); +EXPORT_SYMBOL(__iio_device_register); /** * iio_device_unregister() - unregister a device from the IIO subsystem @@ -1765,23 +1763,8 @@ static void devm_iio_device_unreg(struct device *dev, void *res) iio_device_unregister(*(struct iio_dev **)res); } -/** - * devm_iio_device_register - Resource-managed iio_device_register() - * @dev: Device to allocate iio_dev for - * @indio_dev: Device structure filled by the device driver - * - * Managed iio_device_register. The IIO device registered with this - * function is automatically unregistered on driver detach. This function - * calls iio_device_register() internally. Refer to that function for more - * information. - * - * If an iio_dev registered with this function needs to be unregistered - * separately, devm_iio_device_unregister() must be used. - * - * RETURNS: - * 0 on success, negative error number on failure. - */ -int devm_iio_device_register(struct device *dev, struct iio_dev *indio_dev) +int __devm_iio_device_register(struct device *dev, struct iio_dev *indio_dev, + struct module *this_mod) { struct iio_dev **ptr; int ret; @@ -1791,7 +1774,7 @@ int devm_iio_device_register(struct device *dev, struct iio_dev *indio_dev) return -ENOMEM; *ptr = indio_dev; - ret = iio_device_register(indio_dev); + ret = __iio_device_register(indio_dev, this_mod); if (!ret) devres_add(dev, ptr); else @@ -1799,7 +1782,7 @@ int devm_iio_device_register(struct device *dev, struct iio_dev *indio_dev) return ret; } -EXPORT_SYMBOL_GPL(devm_iio_device_register); +EXPORT_SYMBOL_GPL(__devm_iio_device_register); /** * devm_iio_device_unregister - Resource-managed iio_device_unregister() diff --git a/drivers/iio/industrialio-sw-device.c b/drivers/iio/industrialio-sw-device.c index 81b49cfca452..90df97c542f6 100644 --- a/drivers/iio/industrialio-sw-device.c +++ b/drivers/iio/industrialio-sw-device.c @@ -19,9 +19,9 @@ #include <linux/configfs.h> static struct config_group *iio_devices_group; -static struct config_item_type iio_device_type_group_type; +static const struct config_item_type iio_device_type_group_type; -static struct config_item_type iio_devices_group_type = { +static const struct config_item_type iio_devices_group_type = { .ct_owner = THIS_MODULE, }; @@ -156,7 +156,7 @@ static struct configfs_group_operations device_ops = { .drop_item = &device_drop_group, }; -static struct config_item_type iio_device_type_group_type = { +static const struct config_item_type iio_device_type_group_type = { .ct_group_ops = &device_ops, .ct_owner = THIS_MODULE, }; diff --git a/drivers/iio/industrialio-sw-trigger.c b/drivers/iio/industrialio-sw-trigger.c index 8d24fb159cc9..bc6b7fb43e3a 100644 --- a/drivers/iio/industrialio-sw-trigger.c +++ b/drivers/iio/industrialio-sw-trigger.c @@ -19,9 +19,9 @@ #include <linux/configfs.h> static struct config_group *iio_triggers_group; -static struct config_item_type iio_trigger_type_group_type; +static const struct config_item_type iio_trigger_type_group_type; -static struct config_item_type iio_triggers_group_type = { +static const struct config_item_type iio_triggers_group_type = { .ct_owner = THIS_MODULE, }; @@ -156,7 +156,7 @@ static struct configfs_group_operations trigger_ops = { .drop_item = &trigger_drop_group, }; -static struct config_item_type iio_trigger_type_group_type = { +static const struct config_item_type iio_trigger_type_group_type = { .ct_group_ops = &trigger_ops, .ct_owner = THIS_MODULE, }; diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c index 4061fed93f1f..ce66699c7fcc 100644 --- a/drivers/iio/industrialio-trigger.c +++ b/drivers/iio/industrialio-trigger.c @@ -66,13 +66,12 @@ ATTRIBUTE_GROUPS(iio_trig_dev); static struct iio_trigger *__iio_trigger_find_by_name(const char *name); -int iio_trigger_register(struct iio_trigger *trig_info) +int __iio_trigger_register(struct iio_trigger *trig_info, + struct module *this_mod) { int ret; - /* trig_info->ops is required for the module member */ - if (!trig_info->ops) - return -EINVAL; + trig_info->owner = this_mod; trig_info->id = ida_simple_get(&iio_trigger_ida, 0, 0, GFP_KERNEL); if (trig_info->id < 0) @@ -105,7 +104,7 @@ error_unregister_id: ida_simple_remove(&iio_trigger_ida, trig_info->id); return ret; } -EXPORT_SYMBOL(iio_trigger_register); +EXPORT_SYMBOL(__iio_trigger_register); void iio_trigger_unregister(struct iio_trigger *trig_info) { @@ -206,7 +205,8 @@ EXPORT_SYMBOL(iio_trigger_poll_chained); void iio_trigger_notify_done(struct iio_trigger *trig) { - if (atomic_dec_and_test(&trig->use_count) && trig->ops->try_reenable) + if (atomic_dec_and_test(&trig->use_count) && trig->ops && + trig->ops->try_reenable) if (trig->ops->try_reenable(trig)) /* Missed an interrupt so launch new poll now */ iio_trigger_poll(trig); @@ -250,7 +250,7 @@ static int iio_trigger_attach_poll_func(struct iio_trigger *trig, = bitmap_empty(trig->pool, CONFIG_IIO_CONSUMERS_PER_TRIGGER); /* Prevent the module from being removed whilst attached to a trigger */ - __module_get(pf->indio_dev->info->driver_module); + __module_get(pf->indio_dev->driver_module); /* Get irq number */ pf->irq = iio_trigger_get_irq(trig); @@ -265,7 +265,7 @@ static int iio_trigger_attach_poll_func(struct iio_trigger *trig, goto out_put_irq; /* Enable trigger in driver */ - if (trig->ops->set_trigger_state && notinuse) { + if (trig->ops && trig->ops->set_trigger_state && notinuse) { ret = trig->ops->set_trigger_state(trig, true); if (ret < 0) goto out_free_irq; @@ -286,7 +286,7 @@ out_free_irq: out_put_irq: iio_trigger_put_irq(trig, pf->irq); out_put_module: - module_put(pf->indio_dev->info->driver_module); + module_put(pf->indio_dev->driver_module); return ret; } @@ -298,7 +298,7 @@ static int iio_trigger_detach_poll_func(struct iio_trigger *trig, = (bitmap_weight(trig->pool, CONFIG_IIO_CONSUMERS_PER_TRIGGER) == 1); - if (trig->ops->set_trigger_state && no_other_users) { + if (trig->ops && trig->ops->set_trigger_state && no_other_users) { ret = trig->ops->set_trigger_state(trig, false); if (ret) return ret; @@ -307,7 +307,7 @@ static int iio_trigger_detach_poll_func(struct iio_trigger *trig, trig->attached_own_device = false; iio_trigger_put_irq(trig, pf->irq); free_irq(pf->irq, pf); - module_put(pf->indio_dev->info->driver_module); + module_put(pf->indio_dev->driver_module); return ret; } @@ -428,7 +428,7 @@ static ssize_t iio_trigger_write_current(struct device *dev, goto out_trigger_put; } - if (trig && trig->ops->validate_device) { + if (trig && trig->ops && trig->ops->validate_device) { ret = trig->ops->validate_device(trig, indio_dev); if (ret) goto out_trigger_put; @@ -663,9 +663,10 @@ static void devm_iio_trigger_unreg(struct device *dev, void *res) } /** - * devm_iio_trigger_register - Resource-managed iio_trigger_register() + * __devm_iio_trigger_register - Resource-managed iio_trigger_register() * @dev: device this trigger was allocated for * @trig_info: trigger to register + * @this_mod: module registering the trigger * * Managed iio_trigger_register(). The IIO trigger registered with this * function is automatically unregistered on driver detach. This function @@ -678,7 +679,9 @@ static void devm_iio_trigger_unreg(struct device *dev, void *res) * RETURNS: * 0 on success, negative error number on failure. */ -int devm_iio_trigger_register(struct device *dev, struct iio_trigger *trig_info) +int __devm_iio_trigger_register(struct device *dev, + struct iio_trigger *trig_info, + struct module *this_mod) { struct iio_trigger **ptr; int ret; @@ -688,7 +691,7 @@ int devm_iio_trigger_register(struct device *dev, struct iio_trigger *trig_info) return -ENOMEM; *ptr = trig_info; - ret = iio_trigger_register(trig_info); + ret = __iio_trigger_register(trig_info, this_mod); if (!ret) devres_add(dev, ptr); else @@ -696,7 +699,7 @@ int devm_iio_trigger_register(struct device *dev, struct iio_trigger *trig_info) return ret; } -EXPORT_SYMBOL_GPL(devm_iio_trigger_register); +EXPORT_SYMBOL_GPL(__devm_iio_trigger_register); /** * devm_iio_trigger_unregister - Resource-managed iio_trigger_unregister() diff --git a/drivers/iio/light/acpi-als.c b/drivers/iio/light/acpi-als.c index f0b47c501f4e..c35e2f8df339 100644 --- a/drivers/iio/light/acpi-als.c +++ b/drivers/iio/light/acpi-als.c @@ -171,7 +171,6 @@ static int acpi_als_read_raw(struct iio_dev *indio_dev, } static const struct iio_info acpi_als_info = { - .driver_module = THIS_MODULE, .read_raw = acpi_als_read_raw, }; diff --git a/drivers/iio/light/adjd_s311.c b/drivers/iio/light/adjd_s311.c index 0113fc843a81..e45bb6a277c2 100644 --- a/drivers/iio/light/adjd_s311.c +++ b/drivers/iio/light/adjd_s311.c @@ -245,7 +245,6 @@ static const struct iio_info adjd_s311_info = { .read_raw = adjd_s311_read_raw, .write_raw = adjd_s311_write_raw, .update_scan_mode = adjd_s311_update_scan_mode, - .driver_module = THIS_MODULE, }; static int adjd_s311_probe(struct i2c_client *client, diff --git a/drivers/iio/light/al3320a.c b/drivers/iio/light/al3320a.c index 6aac6513fd41..66623facea9a 100644 --- a/drivers/iio/light/al3320a.c +++ b/drivers/iio/light/al3320a.c @@ -168,7 +168,6 @@ static int al3320a_write_raw(struct iio_dev *indio_dev, } static const struct iio_info al3320a_info = { - .driver_module = THIS_MODULE, .read_raw = al3320a_read_raw, .write_raw = al3320a_write_raw, .attrs = &al3320a_attribute_group, diff --git a/drivers/iio/light/apds9300.c b/drivers/iio/light/apds9300.c index 05eacd1ee40f..5c15736fb93e 100644 --- a/drivers/iio/light/apds9300.c +++ b/drivers/iio/light/apds9300.c @@ -337,12 +337,10 @@ static int apds9300_write_interrupt_config(struct iio_dev *indio_dev, } static const struct iio_info apds9300_info_no_irq = { - .driver_module = THIS_MODULE, .read_raw = apds9300_read_raw, }; static const struct iio_info apds9300_info = { - .driver_module = THIS_MODULE, .read_raw = apds9300_read_raw, .read_event_value = apds9300_read_thresh, .write_event_value = apds9300_write_thresh, diff --git a/drivers/iio/light/apds9960.c b/drivers/iio/light/apds9960.c index 518a47e9377b..a8fa00e31c39 100644 --- a/drivers/iio/light/apds9960.c +++ b/drivers/iio/light/apds9960.c @@ -744,7 +744,6 @@ static int apds9960_write_event_config(struct iio_dev *indio_dev, } static const struct iio_info apds9960_info = { - .driver_module = THIS_MODULE, .attrs = &apds9960_attribute_group, .read_raw = apds9960_read_raw, .write_raw = apds9960_write_raw, diff --git a/drivers/iio/light/bh1750.c b/drivers/iio/light/bh1750.c index 6c61187e630f..a814828e69f5 100644 --- a/drivers/iio/light/bh1750.c +++ b/drivers/iio/light/bh1750.c @@ -217,7 +217,6 @@ static const struct attribute_group bh1750_attribute_group = { }; static const struct iio_info bh1750_info = { - .driver_module = THIS_MODULE, .attrs = &bh1750_attribute_group, .read_raw = bh1750_read_raw, .write_raw = bh1750_write_raw, diff --git a/drivers/iio/light/bh1780.c b/drivers/iio/light/bh1780.c index b54dcba05a82..036f3bbe323c 100644 --- a/drivers/iio/light/bh1780.c +++ b/drivers/iio/light/bh1780.c @@ -128,7 +128,6 @@ static int bh1780_read_raw(struct iio_dev *indio_dev, } static const struct iio_info bh1780_info = { - .driver_module = THIS_MODULE, .read_raw = bh1780_read_raw, .debugfs_reg_access = bh1780_debugfs_reg_access, }; diff --git a/drivers/iio/light/cm32181.c b/drivers/iio/light/cm32181.c index d6fd0dace74f..aebf7dd071af 100644 --- a/drivers/iio/light/cm32181.c +++ b/drivers/iio/light/cm32181.c @@ -292,7 +292,6 @@ static const struct attribute_group cm32181_attribute_group = { }; static const struct iio_info cm32181_info = { - .driver_module = THIS_MODULE, .read_raw = &cm32181_read_raw, .write_raw = &cm32181_write_raw, .attrs = &cm32181_attribute_group, diff --git a/drivers/iio/light/cm3232.c b/drivers/iio/light/cm3232.c index 263e97235ea0..c639cf276ee6 100644 --- a/drivers/iio/light/cm3232.c +++ b/drivers/iio/light/cm3232.c @@ -322,7 +322,6 @@ static const struct attribute_group cm3232_attribute_group = { }; static const struct iio_info cm3232_info = { - .driver_module = THIS_MODULE, .read_raw = &cm3232_read_raw, .write_raw = &cm3232_write_raw, .attrs = &cm3232_attribute_group, diff --git a/drivers/iio/light/cm3323.c b/drivers/iio/light/cm3323.c index d823c112d54b..83b08b6dc60f 100644 --- a/drivers/iio/light/cm3323.c +++ b/drivers/iio/light/cm3323.c @@ -211,7 +211,6 @@ static int cm3323_write_raw(struct iio_dev *indio_dev, } static const struct iio_info cm3323_info = { - .driver_module = THIS_MODULE, .read_raw = cm3323_read_raw, .write_raw = cm3323_write_raw, .attrs = &cm3323_attribute_group, diff --git a/drivers/iio/light/cm3605.c b/drivers/iio/light/cm3605.c index 980624e9ffb5..e454bc6a33c6 100644 --- a/drivers/iio/light/cm3605.c +++ b/drivers/iio/light/cm3605.c @@ -126,7 +126,6 @@ static int cm3605_read_raw(struct iio_dev *indio_dev, } static const struct iio_info cm3605_info = { - .driver_module = THIS_MODULE, .read_raw = cm3605_read_raw, }; diff --git a/drivers/iio/light/cm36651.c b/drivers/iio/light/cm36651.c index 9d66e89c57ef..1dd8ed0121b3 100644 --- a/drivers/iio/light/cm36651.c +++ b/drivers/iio/light/cm36651.c @@ -612,7 +612,6 @@ static const struct attribute_group cm36651_attribute_group = { }; static const struct iio_info cm36651_info = { - .driver_module = THIS_MODULE, .read_raw = &cm36651_read_raw, .write_raw = &cm36651_write_raw, .read_event_value = &cm36651_read_prox_thresh, diff --git a/drivers/iio/light/cros_ec_light_prox.c b/drivers/iio/light/cros_ec_light_prox.c index 721722376fd0..b2a46b390d5c 100644 --- a/drivers/iio/light/cros_ec_light_prox.c +++ b/drivers/iio/light/cros_ec_light_prox.c @@ -175,7 +175,6 @@ static int cros_ec_light_prox_write(struct iio_dev *indio_dev, static const struct iio_info cros_ec_light_prox_info = { .read_raw = &cros_ec_light_prox_read, .write_raw = &cros_ec_light_prox_write, - .driver_module = THIS_MODULE, }; static int cros_ec_light_prox_probe(struct platform_device *pdev) diff --git a/drivers/iio/light/gp2ap020a00f.c b/drivers/iio/light/gp2ap020a00f.c index 6ada9149f142..44b13fbcd093 100644 --- a/drivers/iio/light/gp2ap020a00f.c +++ b/drivers/iio/light/gp2ap020a00f.c @@ -1384,7 +1384,6 @@ static const struct iio_info gp2ap020a00f_info = { .read_event_config = &gp2ap020a00f_read_event_config, .write_event_value = &gp2ap020a00f_write_event_val, .write_event_config = &gp2ap020a00f_write_event_config, - .driver_module = THIS_MODULE, }; static int gp2ap020a00f_buffer_postenable(struct iio_dev *indio_dev) @@ -1481,7 +1480,6 @@ static const struct iio_buffer_setup_ops gp2ap020a00f_buffer_setup_ops = { }; static const struct iio_trigger_ops gp2ap020a00f_trigger_ops = { - .owner = THIS_MODULE, }; static int gp2ap020a00f_probe(struct i2c_client *client, diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c index 059d964772c7..befd693a4a31 100644 --- a/drivers/iio/light/hid-sensor-als.c +++ b/drivers/iio/light/hid-sensor-als.c @@ -177,7 +177,6 @@ static int als_write_raw(struct iio_dev *indio_dev, } static const struct iio_info als_info = { - .driver_module = THIS_MODULE, .read_raw = &als_read_raw, .write_raw = &als_write_raw, }; diff --git a/drivers/iio/light/hid-sensor-prox.c b/drivers/iio/light/hid-sensor-prox.c index 73fced8a63b7..45107f7537b5 100644 --- a/drivers/iio/light/hid-sensor-prox.c +++ b/drivers/iio/light/hid-sensor-prox.c @@ -156,7 +156,6 @@ static int prox_write_raw(struct iio_dev *indio_dev, } static const struct iio_info prox_info = { - .driver_module = THIS_MODULE, .read_raw = &prox_read_raw, .write_raw = &prox_write_raw, }; diff --git a/drivers/iio/light/isl29018.c b/drivers/iio/light/isl29018.c index 61f5924b472d..b45400f8fef4 100644 --- a/drivers/iio/light/isl29018.c +++ b/drivers/iio/light/isl29018.c @@ -624,14 +624,12 @@ static int isl29018_chip_init(struct isl29018_chip *chip) static const struct iio_info isl29018_info = { .attrs = &isl29018_group, - .driver_module = THIS_MODULE, .read_raw = isl29018_read_raw, .write_raw = isl29018_write_raw, }; static const struct iio_info isl29023_info = { .attrs = &isl29023_group, - .driver_module = THIS_MODULE, .read_raw = isl29018_read_raw, .write_raw = isl29018_write_raw, }; diff --git a/drivers/iio/light/isl29028.c b/drivers/iio/light/isl29028.c index 3d09c1fc4dad..f9912ab4f65c 100644 --- a/drivers/iio/light/isl29028.c +++ b/drivers/iio/light/isl29028.c @@ -536,7 +536,6 @@ static const struct iio_chan_spec isl29028_channels[] = { static const struct iio_info isl29028_info = { .attrs = &isl29108_group, - .driver_module = THIS_MODULE, .read_raw = isl29028_read_raw, .write_raw = isl29028_write_raw, }; diff --git a/drivers/iio/light/isl29125.c b/drivers/iio/light/isl29125.c index 1d2c0c8a1d4f..ed38edcd5efe 100644 --- a/drivers/iio/light/isl29125.c +++ b/drivers/iio/light/isl29125.c @@ -214,7 +214,6 @@ static const struct iio_info isl29125_info = { .read_raw = isl29125_read_raw, .write_raw = isl29125_write_raw, .attrs = &isl29125_attribute_group, - .driver_module = THIS_MODULE, }; static int isl29125_buffer_preenable(struct iio_dev *indio_dev) diff --git a/drivers/iio/light/jsa1212.c b/drivers/iio/light/jsa1212.c index e8a8931b4f50..811505d925b3 100644 --- a/drivers/iio/light/jsa1212.c +++ b/drivers/iio/light/jsa1212.c @@ -271,7 +271,6 @@ static const struct iio_chan_spec jsa1212_channels[] = { }; static const struct iio_info jsa1212_info = { - .driver_module = THIS_MODULE, .read_raw = &jsa1212_read_raw, }; diff --git a/drivers/iio/light/lm3533-als.c b/drivers/iio/light/lm3533-als.c index 0443fd2e8757..36208a3652e9 100644 --- a/drivers/iio/light/lm3533-als.c +++ b/drivers/iio/light/lm3533-als.c @@ -827,7 +827,6 @@ static int lm3533_als_disable(struct lm3533_als *als) static const struct iio_info lm3533_als_info = { .attrs = &lm3533_als_attribute_group, .event_attrs = &lm3533_als_event_attribute_group, - .driver_module = THIS_MODULE, .read_raw = &lm3533_als_read_raw, }; diff --git a/drivers/iio/light/ltr501.c b/drivers/iio/light/ltr501.c index 67838edd8b37..830a2d45aa4d 100644 --- a/drivers/iio/light/ltr501.c +++ b/drivers/iio/light/ltr501.c @@ -1158,7 +1158,6 @@ static const struct iio_info ltr501_info_no_irq = { .read_raw = ltr501_read_raw, .write_raw = ltr501_write_raw, .attrs = <r501_attribute_group, - .driver_module = THIS_MODULE, }; static const struct iio_info ltr501_info = { @@ -1169,14 +1168,12 @@ static const struct iio_info ltr501_info = { .write_event_value = <r501_write_event, .read_event_config = <r501_read_event_config, .write_event_config = <r501_write_event_config, - .driver_module = THIS_MODULE, }; static const struct iio_info ltr301_info_no_irq = { .read_raw = ltr501_read_raw, .write_raw = ltr501_write_raw, .attrs = <r301_attribute_group, - .driver_module = THIS_MODULE, }; static const struct iio_info ltr301_info = { @@ -1187,7 +1184,6 @@ static const struct iio_info ltr301_info = { .write_event_value = <r501_write_event, .read_event_config = <r501_read_event_config, .write_event_config = <r501_write_event_config, - .driver_module = THIS_MODULE, }; static struct ltr501_chip_info ltr501_chip_info_tbl[] = { diff --git a/drivers/iio/light/max44000.c b/drivers/iio/light/max44000.c index 81bd8e8da4a6..bcdb0eb9e537 100644 --- a/drivers/iio/light/max44000.c +++ b/drivers/iio/light/max44000.c @@ -402,7 +402,6 @@ static const struct attribute_group max44000_attribute_group = { }; static const struct iio_info max44000_info = { - .driver_module = THIS_MODULE, .read_raw = max44000_read_raw, .write_raw = max44000_write_raw, .write_raw_get_fmt = max44000_write_raw_get_fmt, diff --git a/drivers/iio/light/opt3001.c b/drivers/iio/light/opt3001.c index b91ebc3483ce..54d88b60e303 100644 --- a/drivers/iio/light/opt3001.c +++ b/drivers/iio/light/opt3001.c @@ -585,7 +585,6 @@ err: } static const struct iio_info opt3001_info = { - .driver_module = THIS_MODULE, .attrs = &opt3001_attribute_group, .read_raw = opt3001_read_raw, .write_raw = opt3001_write_raw, diff --git a/drivers/iio/light/pa12203001.c b/drivers/iio/light/pa12203001.c index 76a9e12b46bc..30ea1a088dd9 100644 --- a/drivers/iio/light/pa12203001.c +++ b/drivers/iio/light/pa12203001.c @@ -306,7 +306,6 @@ static int pa12203001_write_raw(struct iio_dev *indio_dev, } static const struct iio_info pa12203001_info = { - .driver_module = THIS_MODULE, .read_raw = pa12203001_read_raw, .write_raw = pa12203001_write_raw, .attrs = &pa12203001_attr_group, diff --git a/drivers/iio/light/rpr0521.c b/drivers/iio/light/rpr0521.c index a6efa12613a2..ffe9ce798ea2 100644 --- a/drivers/iio/light/rpr0521.c +++ b/drivers/iio/light/rpr0521.c @@ -538,7 +538,6 @@ static int rpr0521_pxs_drdy_set_state(struct iio_trigger *trigger, static const struct iio_trigger_ops rpr0521_trigger_ops = { .set_trigger_state = rpr0521_pxs_drdy_set_state, - .owner = THIS_MODULE, }; @@ -830,7 +829,6 @@ static int rpr0521_write_raw(struct iio_dev *indio_dev, } static const struct iio_info rpr0521_info = { - .driver_module = THIS_MODULE, .read_raw = rpr0521_read_raw, .write_raw = rpr0521_write_raw, .attrs = &rpr0521_attribute_group, diff --git a/drivers/iio/light/si1145.c b/drivers/iio/light/si1145.c index 096034c126a4..76f16f9c7616 100644 --- a/drivers/iio/light/si1145.c +++ b/drivers/iio/light/si1145.c @@ -989,14 +989,12 @@ static const struct attribute_group si114x_attribute_group = { static const struct iio_info si1132_info = { .read_raw = si1145_read_raw, .write_raw = si1145_write_raw, - .driver_module = THIS_MODULE, .attrs = &si1132_attribute_group, }; static const struct iio_info si114x_info = { .read_raw = si1145_read_raw, .write_raw = si1145_write_raw, - .driver_module = THIS_MODULE, .attrs = &si114x_attribute_group, }; @@ -1237,7 +1235,6 @@ disable: } static const struct iio_trigger_ops si1145_trigger_ops = { - .owner = THIS_MODULE, .set_trigger_state = si1145_trigger_set_state, }; diff --git a/drivers/iio/light/stk3310.c b/drivers/iio/light/stk3310.c index 45cf8b0a4363..6e2a169da950 100644 --- a/drivers/iio/light/stk3310.c +++ b/drivers/iio/light/stk3310.c @@ -409,7 +409,6 @@ static int stk3310_write_raw(struct iio_dev *indio_dev, } static const struct iio_info stk3310_info = { - .driver_module = THIS_MODULE, .read_raw = stk3310_read_raw, .write_raw = stk3310_write_raw, .attrs = &stk3310_attribute_group, diff --git a/drivers/iio/light/tcs3414.c b/drivers/iio/light/tcs3414.c index a795afb7667b..205e5659ce6b 100644 --- a/drivers/iio/light/tcs3414.c +++ b/drivers/iio/light/tcs3414.c @@ -241,7 +241,6 @@ static const struct iio_info tcs3414_info = { .read_raw = tcs3414_read_raw, .write_raw = tcs3414_write_raw, .attrs = &tcs3414_attribute_group, - .driver_module = THIS_MODULE, }; static int tcs3414_buffer_preenable(struct iio_dev *indio_dev) diff --git a/drivers/iio/light/tcs3472.c b/drivers/iio/light/tcs3472.c index 09e6ca5e332e..e7923b514d7a 100644 --- a/drivers/iio/light/tcs3472.c +++ b/drivers/iio/light/tcs3472.c @@ -13,7 +13,7 @@ * * Datasheet: http://ams.com/eng/content/download/319364/1117183/file/TCS3472_Datasheet_EN_v2.pdf * - * TODO: interrupt support, thresholds, wait time + * TODO: wait time */ #include <linux/module.h> @@ -23,6 +23,7 @@ #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> +#include <linux/iio/events.h> #include <linux/iio/trigger_consumer.h> #include <linux/iio/buffer.h> #include <linux/iio/triggered_buffer.h> @@ -31,12 +32,15 @@ #define TCS3472_COMMAND BIT(7) #define TCS3472_AUTO_INCR BIT(5) +#define TCS3472_SPECIAL_FUNC (BIT(5) | BIT(6)) + +#define TCS3472_INTR_CLEAR (TCS3472_COMMAND | TCS3472_SPECIAL_FUNC | 0x06) #define TCS3472_ENABLE (TCS3472_COMMAND | 0x00) #define TCS3472_ATIME (TCS3472_COMMAND | 0x01) #define TCS3472_WTIME (TCS3472_COMMAND | 0x03) -#define TCS3472_AILT (TCS3472_COMMAND | 0x04) -#define TCS3472_AIHT (TCS3472_COMMAND | 0x06) +#define TCS3472_AILT (TCS3472_COMMAND | TCS3472_AUTO_INCR | 0x04) +#define TCS3472_AIHT (TCS3472_COMMAND | TCS3472_AUTO_INCR | 0x06) #define TCS3472_PERS (TCS3472_COMMAND | 0x0c) #define TCS3472_CONFIG (TCS3472_COMMAND | 0x0d) #define TCS3472_CONTROL (TCS3472_COMMAND | 0x0f) @@ -47,19 +51,42 @@ #define TCS3472_GDATA (TCS3472_COMMAND | TCS3472_AUTO_INCR | 0x18) #define TCS3472_BDATA (TCS3472_COMMAND | TCS3472_AUTO_INCR | 0x1a) +#define TCS3472_STATUS_AINT BIT(4) #define TCS3472_STATUS_AVALID BIT(0) +#define TCS3472_ENABLE_AIEN BIT(4) #define TCS3472_ENABLE_AEN BIT(1) #define TCS3472_ENABLE_PON BIT(0) #define TCS3472_CONTROL_AGAIN_MASK (BIT(0) | BIT(1)) struct tcs3472_data { struct i2c_client *client; + struct mutex lock; + u16 low_thresh; + u16 high_thresh; u8 enable; u8 control; u8 atime; + u8 apers; u16 buffer[8]; /* 4 16-bit channels + 64-bit timestamp */ }; +static const struct iio_event_spec tcs3472_events[] = { + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_RISING, + .mask_separate = BIT(IIO_EV_INFO_VALUE), + }, { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_FALLING, + .mask_separate = BIT(IIO_EV_INFO_VALUE), + }, { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_EITHER, + .mask_separate = BIT(IIO_EV_INFO_ENABLE) | + BIT(IIO_EV_INFO_PERIOD), + }, +}; + #define TCS3472_CHANNEL(_color, _si, _addr) { \ .type = IIO_INTENSITY, \ .modified = 1, \ @@ -75,6 +102,8 @@ struct tcs3472_data { .storagebits = 16, \ .endianness = IIO_CPU, \ }, \ + .event_spec = _si ? NULL : tcs3472_events, \ + .num_event_specs = _si ? 0 : ARRAY_SIZE(tcs3472_events), \ } static const int tcs3472_agains[] = { 1, 4, 16, 60 }; @@ -182,6 +211,166 @@ static int tcs3472_write_raw(struct iio_dev *indio_dev, return -EINVAL; } +/* + * Translation from APERS field value to the number of consecutive out-of-range + * clear channel values before an interrupt is generated + */ +static const int tcs3472_intr_pers[] = { + 0, 1, 2, 3, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60 +}; + +static int tcs3472_read_event(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 tcs3472_data *data = iio_priv(indio_dev); + int ret; + unsigned int period; + + mutex_lock(&data->lock); + + switch (info) { + case IIO_EV_INFO_VALUE: + *val = (dir == IIO_EV_DIR_RISING) ? + data->high_thresh : data->low_thresh; + ret = IIO_VAL_INT; + break; + case IIO_EV_INFO_PERIOD: + period = (256 - data->atime) * 2400 * + tcs3472_intr_pers[data->apers]; + *val = period / USEC_PER_SEC; + *val2 = period % USEC_PER_SEC; + ret = IIO_VAL_INT_PLUS_MICRO; + break; + default: + ret = -EINVAL; + break; + } + + mutex_unlock(&data->lock); + + return ret; +} + +static int tcs3472_write_event(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 tcs3472_data *data = iio_priv(indio_dev); + int ret; + u8 command; + int period; + int i; + + mutex_lock(&data->lock); + switch (info) { + case IIO_EV_INFO_VALUE: + switch (dir) { + case IIO_EV_DIR_RISING: + command = TCS3472_AIHT; + break; + case IIO_EV_DIR_FALLING: + command = TCS3472_AILT; + break; + default: + ret = -EINVAL; + goto error; + } + ret = i2c_smbus_write_word_data(data->client, command, val); + if (ret) + goto error; + + if (dir == IIO_EV_DIR_RISING) + data->high_thresh = val; + else + data->low_thresh = val; + break; + case IIO_EV_INFO_PERIOD: + period = val * USEC_PER_SEC + val2; + for (i = 1; i < ARRAY_SIZE(tcs3472_intr_pers) - 1; i++) { + if (period <= (256 - data->atime) * 2400 * + tcs3472_intr_pers[i]) + break; + } + ret = i2c_smbus_write_byte_data(data->client, TCS3472_PERS, i); + if (ret) + goto error; + + data->apers = i; + break; + default: + ret = -EINVAL; + break; + } +error: + mutex_unlock(&data->lock); + + return ret; +} + +static int tcs3472_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 tcs3472_data *data = iio_priv(indio_dev); + int ret; + + mutex_lock(&data->lock); + ret = !!(data->enable & TCS3472_ENABLE_AIEN); + mutex_unlock(&data->lock); + + return ret; +} + +static int tcs3472_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 tcs3472_data *data = iio_priv(indio_dev); + int ret = 0; + u8 enable_old; + + mutex_lock(&data->lock); + + enable_old = data->enable; + + if (state) + data->enable |= TCS3472_ENABLE_AIEN; + else + data->enable &= ~TCS3472_ENABLE_AIEN; + + if (enable_old != data->enable) { + ret = i2c_smbus_write_byte_data(data->client, TCS3472_ENABLE, + data->enable); + if (ret) + data->enable = enable_old; + } + mutex_unlock(&data->lock); + + return ret; +} + +static irqreturn_t tcs3472_event_handler(int irq, void *priv) +{ + struct iio_dev *indio_dev = priv; + struct tcs3472_data *data = iio_priv(indio_dev); + int ret; + + ret = i2c_smbus_read_byte_data(data->client, TCS3472_STATUS); + if (ret >= 0 && (ret & TCS3472_STATUS_AINT)) { + iio_push_event(indio_dev, IIO_UNMOD_EVENT_CODE(IIO_INTENSITY, 0, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_EITHER), + iio_get_time_ns(indio_dev)); + + i2c_smbus_read_byte_data(data->client, TCS3472_INTR_CLEAR); + } + + return IRQ_HANDLED; +} + static irqreturn_t tcs3472_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; @@ -245,8 +434,11 @@ static const struct attribute_group tcs3472_attribute_group = { static const struct iio_info tcs3472_info = { .read_raw = tcs3472_read_raw, .write_raw = tcs3472_write_raw, + .read_event_value = tcs3472_read_event, + .write_event_value = tcs3472_write_event, + .read_event_config = tcs3472_read_event_config, + .write_event_config = tcs3472_write_event_config, .attrs = &tcs3472_attribute_group, - .driver_module = THIS_MODULE, }; static int tcs3472_probe(struct i2c_client *client, @@ -263,6 +455,7 @@ static int tcs3472_probe(struct i2c_client *client, data = iio_priv(indio_dev); i2c_set_clientdata(client, indio_dev); data->client = client; + mutex_init(&data->lock); indio_dev->dev.parent = &client->dev; indio_dev->info = &tcs3472_info; @@ -292,12 +485,29 @@ static int tcs3472_probe(struct i2c_client *client, return ret; data->atime = ret; + ret = i2c_smbus_read_word_data(data->client, TCS3472_AILT); + if (ret < 0) + return ret; + data->low_thresh = ret; + + ret = i2c_smbus_read_word_data(data->client, TCS3472_AIHT); + if (ret < 0) + return ret; + data->high_thresh = ret; + + data->apers = 1; + ret = i2c_smbus_write_byte_data(data->client, TCS3472_PERS, + data->apers); + if (ret < 0) + return ret; + ret = i2c_smbus_read_byte_data(data->client, TCS3472_ENABLE); if (ret < 0) return ret; /* enable device */ data->enable = ret | TCS3472_ENABLE_PON | TCS3472_ENABLE_AEN; + data->enable &= ~TCS3472_ENABLE_AIEN; ret = i2c_smbus_write_byte_data(data->client, TCS3472_ENABLE, data->enable); if (ret < 0) @@ -308,12 +518,24 @@ static int tcs3472_probe(struct i2c_client *client, if (ret < 0) return ret; + if (client->irq) { + ret = request_threaded_irq(client->irq, NULL, + tcs3472_event_handler, + IRQF_TRIGGER_FALLING | IRQF_SHARED | + IRQF_ONESHOT, + client->name, indio_dev); + if (ret) + goto buffer_cleanup; + } + ret = iio_device_register(indio_dev); if (ret < 0) - goto buffer_cleanup; + goto free_irq; return 0; +free_irq: + free_irq(client->irq, indio_dev); buffer_cleanup: iio_triggered_buffer_cleanup(indio_dev); return ret; @@ -321,8 +543,19 @@ buffer_cleanup: static int tcs3472_powerdown(struct tcs3472_data *data) { - return i2c_smbus_write_byte_data(data->client, TCS3472_ENABLE, - data->enable & ~(TCS3472_ENABLE_AEN | TCS3472_ENABLE_PON)); + int ret; + u8 enable_mask = TCS3472_ENABLE_AEN | TCS3472_ENABLE_PON; + + mutex_lock(&data->lock); + + ret = i2c_smbus_write_byte_data(data->client, TCS3472_ENABLE, + data->enable & ~enable_mask); + if (!ret) + data->enable &= ~enable_mask; + + mutex_unlock(&data->lock); + + return ret; } static int tcs3472_remove(struct i2c_client *client) @@ -330,6 +563,7 @@ static int tcs3472_remove(struct i2c_client *client) struct iio_dev *indio_dev = i2c_get_clientdata(client); iio_device_unregister(indio_dev); + free_irq(client->irq, indio_dev); iio_triggered_buffer_cleanup(indio_dev); tcs3472_powerdown(iio_priv(indio_dev)); @@ -348,8 +582,19 @@ static int tcs3472_resume(struct device *dev) { struct tcs3472_data *data = iio_priv(i2c_get_clientdata( to_i2c_client(dev))); - return i2c_smbus_write_byte_data(data->client, TCS3472_ENABLE, - data->enable | (TCS3472_ENABLE_AEN | TCS3472_ENABLE_PON)); + int ret; + u8 enable_mask = TCS3472_ENABLE_AEN | TCS3472_ENABLE_PON; + + mutex_lock(&data->lock); + + ret = i2c_smbus_write_byte_data(data->client, TCS3472_ENABLE, + data->enable | enable_mask); + if (!ret) + data->enable |= enable_mask; + + mutex_unlock(&data->lock); + + return ret; } #endif diff --git a/drivers/iio/light/tsl2563.c b/drivers/iio/light/tsl2563.c index 7599693f7fe9..6bbb0b1e6032 100644 --- a/drivers/iio/light/tsl2563.c +++ b/drivers/iio/light/tsl2563.c @@ -697,13 +697,11 @@ static int tsl2563_read_interrupt_config(struct iio_dev *indio_dev, } static const struct iio_info tsl2563_info_no_irq = { - .driver_module = THIS_MODULE, .read_raw = &tsl2563_read_raw, .write_raw = &tsl2563_write_raw, }; static const struct iio_info tsl2563_info = { - .driver_module = THIS_MODULE, .read_raw = &tsl2563_read_raw, .write_raw = &tsl2563_write_raw, .read_event_value = &tsl2563_read_thresh, diff --git a/drivers/iio/light/tsl2583.c b/drivers/iio/light/tsl2583.c index fb711ed4862e..f2e50edaa242 100644 --- a/drivers/iio/light/tsl2583.c +++ b/drivers/iio/light/tsl2583.c @@ -804,7 +804,6 @@ static int tsl2583_write_raw(struct iio_dev *indio_dev, static const struct iio_info tsl2583_info = { .attrs = &tsl2583_attribute_group, - .driver_module = THIS_MODULE, .read_raw = tsl2583_read_raw, .write_raw = tsl2583_write_raw, }; diff --git a/drivers/iio/light/tsl4531.c b/drivers/iio/light/tsl4531.c index cf94ec72b181..06171cb76e23 100644 --- a/drivers/iio/light/tsl4531.c +++ b/drivers/iio/light/tsl4531.c @@ -144,7 +144,6 @@ static const struct iio_info tsl4531_info = { .read_raw = tsl4531_read_raw, .write_raw = tsl4531_write_raw, .attrs = &tsl4531_attribute_group, - .driver_module = THIS_MODULE, }; static int tsl4531_check_id(struct i2c_client *client) diff --git a/drivers/iio/light/us5182d.c b/drivers/iio/light/us5182d.c index d571ad7291ed..68e52943879a 100644 --- a/drivers/iio/light/us5182d.c +++ b/drivers/iio/light/us5182d.c @@ -714,7 +714,6 @@ err: } static const struct iio_info us5182d_info = { - .driver_module = THIS_MODULE, .read_raw = us5182d_read_raw, .write_raw = us5182d_write_raw, .attrs = &us5182d_attr_group, diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c index 360b6e98137a..c599a90506ad 100644 --- a/drivers/iio/light/vcnl4000.c +++ b/drivers/iio/light/vcnl4000.c @@ -155,7 +155,6 @@ static int vcnl4000_read_raw(struct iio_dev *indio_dev, static const struct iio_info vcnl4000_info = { .read_raw = vcnl4000_read_raw, - .driver_module = THIS_MODULE, }; static int vcnl4000_probe(struct i2c_client *client, diff --git a/drivers/iio/light/veml6070.c b/drivers/iio/light/veml6070.c index bc1c4cb782cd..f4bf3c5b5eda 100644 --- a/drivers/iio/light/veml6070.c +++ b/drivers/iio/light/veml6070.c @@ -136,7 +136,6 @@ static int veml6070_read_raw(struct iio_dev *indio_dev, static const struct iio_info veml6070_info = { .read_raw = veml6070_read_raw, - .driver_module = THIS_MODULE, }; static int veml6070_probe(struct i2c_client *client, diff --git a/drivers/iio/light/vl6180.c b/drivers/iio/light/vl6180.c index 6e25b724d941..192c77ef3608 100644 --- a/drivers/iio/light/vl6180.c +++ b/drivers/iio/light/vl6180.c @@ -24,6 +24,7 @@ #include <linux/err.h> #include <linux/of.h> #include <linux/delay.h> +#include <linux/util_macros.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> @@ -86,6 +87,8 @@ struct vl6180_data { struct i2c_client *client; struct mutex lock; + unsigned int als_gain_milli; + unsigned int als_it_ms; }; enum { VL6180_ALS, VL6180_RANGE, VL6180_PROX }; @@ -275,19 +278,17 @@ static const struct iio_chan_spec vl6180_channels[] = { }; /* - * Columns 3 & 4 represent the same value in decimal and hex notations. - * Kept in order to avoid the datatype conversion while reading the - * hardware_gain. + * Available Ambient Light Sensor gain settings, 1/1000th, and + * corresponding setting for the VL6180_ALS_GAIN register */ -static const int vl6180_als_gain[8][4] = { - { 1, 0, 70, VL6180_ALS_GAIN_1 }, - { 1, 250000, 69, VL6180_ALS_GAIN_1_25 }, - { 1, 670000, 68, VL6180_ALS_GAIN_1_67 }, - { 2, 500000, 67, VL6180_ALS_GAIN_2_5 }, - { 5, 0, 66, VL6180_ALS_GAIN_5 }, - { 10, 0, 65, VL6180_ALS_GAIN_10 }, - { 20, 0, 64, VL6180_ALS_GAIN_20 }, - { 40, 0, 71, VL6180_ALS_GAIN_40 } +static const int vl6180_als_gain_tab[8] = { + 1000, 1250, 1670, 2500, 5000, 10000, 20000, 40000 +}; +static const u8 vl6180_als_gain_tab_bits[8] = { + VL6180_ALS_GAIN_1, VL6180_ALS_GAIN_1_25, + VL6180_ALS_GAIN_1_67, VL6180_ALS_GAIN_2_5, + VL6180_ALS_GAIN_5, VL6180_ALS_GAIN_10, + VL6180_ALS_GAIN_20, VL6180_ALS_GAIN_40 }; static int vl6180_read_raw(struct iio_dev *indio_dev, @@ -295,7 +296,7 @@ static int vl6180_read_raw(struct iio_dev *indio_dev, int *val, int *val2, long mask) { struct vl6180_data *data = iio_priv(indio_dev); - int ret, i; + int ret; switch (mask) { case IIO_CHAN_INFO_RAW: @@ -306,19 +307,20 @@ static int vl6180_read_raw(struct iio_dev *indio_dev, return IIO_VAL_INT; case IIO_CHAN_INFO_INT_TIME: - ret = vl6180_read_word(data->client, VL6180_ALS_IT); - if (ret < 0) - return ret; - *val = 0; /* 1 count = 1ms (0 = 1ms) */ - *val2 = (ret + 1) * 1000; /* convert to seconds */ + *val = data->als_it_ms; + *val2 = 1000; + + return IIO_VAL_FRACTIONAL; - return IIO_VAL_INT_PLUS_MICRO; case IIO_CHAN_INFO_SCALE: switch (chan->type) { case IIO_LIGHT: - *val = 0; /* one ALS count is 0.32 Lux */ - *val2 = 320000; - break; + /* one ALS count is 0.32 Lux @ gain 1, IT 100 ms */ + *val = 32000; /* 0.32 * 1000 * 100 */ + *val2 = data->als_gain_milli * data->als_it_ms; + + return IIO_VAL_FRACTIONAL; + case IIO_DISTANCE: *val = 0; /* sensor reports mm, scale to meter */ *val2 = 1000; @@ -329,17 +331,11 @@ static int vl6180_read_raw(struct iio_dev *indio_dev, return IIO_VAL_INT_PLUS_MICRO; case IIO_CHAN_INFO_HARDWAREGAIN: - ret = vl6180_read_byte(data->client, VL6180_ALS_GAIN); - if (ret < 0) - return -EINVAL; - for (i = 0; i < ARRAY_SIZE(vl6180_als_gain); i++) { - if (ret == vl6180_als_gain[i][2]) { - *val = vl6180_als_gain[i][0]; - *val2 = vl6180_als_gain[i][1]; - } - } + *val = data->als_gain_milli; + *val2 = 1000; + + return IIO_VAL_FRACTIONAL; - return IIO_VAL_INT_PLUS_MICRO; default: return -EINVAL; } @@ -365,37 +361,53 @@ static int vl6180_hold(struct vl6180_data *data, bool hold) static int vl6180_set_als_gain(struct vl6180_data *data, int val, int val2) { - int i, ret; - - for (i = 0; i < ARRAY_SIZE(vl6180_als_gain); i++) { - if (val == vl6180_als_gain[i][0] && - val2 == vl6180_als_gain[i][1]) { - mutex_lock(&data->lock); - ret = vl6180_hold(data, true); - if (ret < 0) - goto fail; - ret = vl6180_write_byte(data->client, VL6180_ALS_GAIN, - vl6180_als_gain[i][3]); -fail: - vl6180_hold(data, false); - mutex_unlock(&data->lock); - return ret; - } - } + int i, ret, gain; - return -EINVAL; + if (val < 1 || val > 40) + return -EINVAL; + + gain = (val * 1000000 + val2) / 1000; + if (gain < 1 || gain > 40000) + return -EINVAL; + + i = find_closest(gain, vl6180_als_gain_tab, + ARRAY_SIZE(vl6180_als_gain_tab)); + + mutex_lock(&data->lock); + ret = vl6180_hold(data, true); + if (ret < 0) + goto fail; + + ret = vl6180_write_byte(data->client, VL6180_ALS_GAIN, + vl6180_als_gain_tab_bits[i]); + + if (ret >= 0) + data->als_gain_milli = vl6180_als_gain_tab[i]; + +fail: + vl6180_hold(data, false); + mutex_unlock(&data->lock); + return ret; } -static int vl6180_set_it(struct vl6180_data *data, int val2) +static int vl6180_set_it(struct vl6180_data *data, int val, int val2) { - int ret; + int ret, it_ms; + + it_ms = (val2 + 500) / 1000; /* round to ms */ + if (val != 0 || it_ms < 1 || it_ms > 512) + return -EINVAL; mutex_lock(&data->lock); ret = vl6180_hold(data, true); if (ret < 0) goto fail; - ret = vl6180_write_word(data->client, VL6180_ALS_IT, - (val2 - 500) / 1000); /* write value in ms */ + + ret = vl6180_write_word(data->client, VL6180_ALS_IT, it_ms - 1); + + if (ret >= 0) + data->als_it_ms = it_ms; + fail: vl6180_hold(data, false); mutex_unlock(&data->lock); @@ -411,10 +423,8 @@ static int vl6180_write_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_INT_TIME: - if (val != 0 || val2 < 500 || val2 >= 512500) - return -EINVAL; + return vl6180_set_it(data, val, val2); - return vl6180_set_it(data, val2); case IIO_CHAN_INFO_HARDWAREGAIN: if (chan->type != IIO_LIGHT) return -EINVAL; @@ -429,7 +439,6 @@ static const struct iio_info vl6180_info = { .read_raw = vl6180_read_raw, .write_raw = vl6180_write_raw, .attrs = &vl6180_attribute_group, - .driver_module = THIS_MODULE, }; static int vl6180_init(struct vl6180_data *data) @@ -468,11 +477,13 @@ static int vl6180_init(struct vl6180_data *data) return ret; /* ALS integration time: 100ms */ + data->als_it_ms = 100; ret = vl6180_write_word(client, VL6180_ALS_IT, VL6180_ALS_IT_100); if (ret < 0) return ret; /* ALS gain: 1 */ + data->als_gain_milli = 1000; ret = vl6180_write_byte(client, VL6180_ALS_GAIN, VL6180_ALS_GAIN_1); if (ret < 0) return ret; diff --git a/drivers/iio/magnetometer/ak8974.c b/drivers/iio/magnetometer/ak8974.c index 0bff76e96950..93be1f4c0f27 100644 --- a/drivers/iio/magnetometer/ak8974.c +++ b/drivers/iio/magnetometer/ak8974.c @@ -658,7 +658,6 @@ static const unsigned long ak8974_scan_masks[] = { 0x7, 0 }; static const struct iio_info ak8974_info = { .read_raw = &ak8974_read_raw, - .driver_module = THIS_MODULE, }; static bool ak8974_writeable_reg(struct device *dev, unsigned int reg) diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c index 4ff883942f7b..c09329069d0a 100644 --- a/drivers/iio/magnetometer/ak8975.c +++ b/drivers/iio/magnetometer/ak8975.c @@ -781,7 +781,6 @@ static const unsigned long ak8975_scan_masks[] = { 0x7, 0 }; static const struct iio_info ak8975_info = { .read_raw = &ak8975_read_raw, - .driver_module = THIS_MODULE, }; #ifdef CONFIG_ACPI diff --git a/drivers/iio/magnetometer/bmc150_magn.c b/drivers/iio/magnetometer/bmc150_magn.c index d104fb8d9379..d91cb845e3d6 100644 --- a/drivers/iio/magnetometer/bmc150_magn.c +++ b/drivers/iio/magnetometer/bmc150_magn.c @@ -651,7 +651,6 @@ static const struct iio_info bmc150_magn_info = { .attrs = &bmc150_magn_attrs_group, .read_raw = bmc150_magn_read_raw, .write_raw = bmc150_magn_write_raw, - .driver_module = THIS_MODULE, }; static const unsigned long bmc150_magn_scan_masks[] = { @@ -811,7 +810,6 @@ err_unlock: static const struct iio_trigger_ops bmc150_magn_trigger_ops = { .set_trigger_state = bmc150_magn_data_rdy_trigger_set_state, .try_reenable = bmc150_magn_trig_try_reen, - .owner = THIS_MODULE, }; static int bmc150_magn_buffer_preenable(struct iio_dev *indio_dev) diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c b/drivers/iio/magnetometer/hid-sensor-magn-3d.c index 0e791b02ed4a..a1fd9d591818 100644 --- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c +++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c @@ -282,7 +282,6 @@ static int magn_3d_write_raw(struct iio_dev *indio_dev, } static const struct iio_info magn_3d_info = { - .driver_module = THIS_MODULE, .read_raw = &magn_3d_read_raw, .write_raw = &magn_3d_write_raw, }; diff --git a/drivers/iio/magnetometer/hmc5843_core.c b/drivers/iio/magnetometer/hmc5843_core.c index ba3e2a374ee5..ada142fb7aa3 100644 --- a/drivers/iio/magnetometer/hmc5843_core.c +++ b/drivers/iio/magnetometer/hmc5843_core.c @@ -597,7 +597,6 @@ static const struct iio_info hmc5843_info = { .read_raw = &hmc5843_read_raw, .write_raw = &hmc5843_write_raw, .write_raw_get_fmt = &hmc5843_write_raw_get_fmt, - .driver_module = THIS_MODULE, }; static const unsigned long hmc5843_scan_masks[] = {0x7, 0}; diff --git a/drivers/iio/magnetometer/mag3110.c b/drivers/iio/magnetometer/mag3110.c index dad8d57f7402..b34ace76d31b 100644 --- a/drivers/iio/magnetometer/mag3110.c +++ b/drivers/iio/magnetometer/mag3110.c @@ -333,7 +333,6 @@ static const struct iio_info mag3110_info = { .attrs = &mag3110_group, .read_raw = &mag3110_read_raw, .write_raw = &mag3110_write_raw, - .driver_module = THIS_MODULE, }; static const unsigned long mag3110_scan_masks[] = {0x7, 0xf, 0}; diff --git a/drivers/iio/magnetometer/mmc35240.c b/drivers/iio/magnetometer/mmc35240.c index 176e14a61558..6b640c6338c9 100644 --- a/drivers/iio/magnetometer/mmc35240.c +++ b/drivers/iio/magnetometer/mmc35240.c @@ -418,7 +418,6 @@ static int mmc35240_write_raw(struct iio_dev *indio_dev, } static const struct iio_info mmc35240_info = { - .driver_module = THIS_MODULE, .read_raw = mmc35240_read_raw, .write_raw = mmc35240_write_raw, .attrs = &mmc35240_attribute_group, diff --git a/drivers/iio/magnetometer/st_magn_core.c b/drivers/iio/magnetometer/st_magn_core.c index 08aafba4481c..72f6d1335a04 100644 --- a/drivers/iio/magnetometer/st_magn_core.c +++ b/drivers/iio/magnetometer/st_magn_core.c @@ -317,7 +317,14 @@ static const struct st_sensor_settings st_magn_sensors_settings[] = { }, .drdy_irq = { /* drdy line is routed drdy pin */ - .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR, + .stat_drdy = { + .addr = ST_SENSORS_DEFAULT_STAT_ADDR, + .mask = 0x07, + }, + }, + .sim = { + .addr = 0x22, + .value = BIT(2), }, .multi_read_bit = true, .bootime = 2, @@ -359,9 +366,14 @@ static const struct st_sensor_settings st_magn_sensors_settings[] = { .mask = 0x10, }, .drdy_irq = { - .addr = 0x62, - .mask_int1 = 0x01, - .addr_stat_drdy = 0x67, + .int1 = { + .addr = 0x62, + .mask = 0x01, + }, + .stat_drdy = { + .addr = 0x67, + .mask = 0x07, + }, }, .multi_read_bit = false, .bootime = 2, @@ -438,7 +450,6 @@ static const struct attribute_group st_magn_attribute_group = { }; static const struct iio_info magn_info = { - .driver_module = THIS_MODULE, .attrs = &st_magn_attribute_group, .read_raw = &st_magn_read_raw, .write_raw = &st_magn_write_raw, @@ -447,7 +458,6 @@ static const struct iio_info magn_info = { #ifdef CONFIG_IIO_TRIGGER static const struct iio_trigger_ops st_magn_trigger_ops = { - .owner = THIS_MODULE, .set_trigger_state = ST_MAGN_TRIGGER_SET_STATE, .validate_device = st_sensors_validate_device, }; diff --git a/drivers/iio/multiplexer/iio-mux.c b/drivers/iio/multiplexer/iio-mux.c index 37ba007f8dca..60621ccd67e4 100644 --- a/drivers/iio/multiplexer/iio-mux.c +++ b/drivers/iio/multiplexer/iio-mux.c @@ -173,7 +173,6 @@ static const struct iio_info mux_info = { .read_raw = mux_read_raw, .read_avail = mux_read_avail, .write_raw = mux_write_raw, - .driver_module = THIS_MODULE, }; static ssize_t mux_read_ext_info(struct iio_dev *indio_dev, uintptr_t private, @@ -285,6 +284,9 @@ static int mux_configure_channel(struct device *dev, struct mux *mux, child->ext_info_cache = devm_kzalloc(dev, sizeof(*child->ext_info_cache) * num_ext_info, GFP_KERNEL); + if (!child->ext_info_cache) + return -ENOMEM; + for (i = 0; i < num_ext_info; ++i) { child->ext_info_cache[i].size = -1; @@ -309,6 +311,9 @@ static int mux_configure_channel(struct device *dev, struct mux *mux, child->ext_info_cache[i].data = devm_kmemdup(dev, page, ret + 1, GFP_KERNEL); + if (!child->ext_info_cache[i].data) + return -ENOMEM; + child->ext_info_cache[i].data[ret] = 0; child->ext_info_cache[i].size = ret; } diff --git a/drivers/iio/orientation/hid-sensor-incl-3d.c b/drivers/iio/orientation/hid-sensor-incl-3d.c index fd1b3696ee42..1e5451d1ff88 100644 --- a/drivers/iio/orientation/hid-sensor-incl-3d.c +++ b/drivers/iio/orientation/hid-sensor-incl-3d.c @@ -186,7 +186,6 @@ static int incl_3d_write_raw(struct iio_dev *indio_dev, } static const struct iio_info incl_3d_info = { - .driver_module = THIS_MODULE, .read_raw = &incl_3d_read_raw, .write_raw = &incl_3d_write_raw, }; diff --git a/drivers/iio/orientation/hid-sensor-rotation.c b/drivers/iio/orientation/hid-sensor-rotation.c index 98fe0c5df380..a69db2002414 100644 --- a/drivers/iio/orientation/hid-sensor-rotation.c +++ b/drivers/iio/orientation/hid-sensor-rotation.c @@ -138,7 +138,6 @@ static int dev_rot_write_raw(struct iio_dev *indio_dev, } static const struct iio_info dev_rot_info = { - .driver_module = THIS_MODULE, .read_raw_multi = &dev_rot_read_raw, .write_raw = &dev_rot_write_raw, }; diff --git a/drivers/iio/potentiometer/ds1803.c b/drivers/iio/potentiometer/ds1803.c index fb9e2a337dc2..9b0ff4ab2f9c 100644 --- a/drivers/iio/potentiometer/ds1803.c +++ b/drivers/iio/potentiometer/ds1803.c @@ -110,7 +110,6 @@ static int ds1803_write_raw(struct iio_dev *indio_dev, static const struct iio_info ds1803_info = { .read_raw = ds1803_read_raw, .write_raw = ds1803_write_raw, - .driver_module = THIS_MODULE, }; static int ds1803_probe(struct i2c_client *client, diff --git a/drivers/iio/potentiometer/max5481.c b/drivers/iio/potentiometer/max5481.c index 926554991244..ffe2761333a2 100644 --- a/drivers/iio/potentiometer/max5481.c +++ b/drivers/iio/potentiometer/max5481.c @@ -119,7 +119,6 @@ static int max5481_write_raw(struct iio_dev *indio_dev, static const struct iio_info max5481_info = { .read_raw = max5481_read_raw, .write_raw = max5481_write_raw, - .driver_module = THIS_MODULE, }; #if defined(CONFIG_OF) @@ -207,7 +206,6 @@ MODULE_DEVICE_TABLE(acpi, max5481_acpi_match); static struct spi_driver max5481_driver = { .driver = { .name = "max5481", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(max5481_match), .acpi_match_table = ACPI_PTR(max5481_acpi_match), }, diff --git a/drivers/iio/potentiometer/max5487.c b/drivers/iio/potentiometer/max5487.c index 6c50939a2e83..5042d3e09b12 100644 --- a/drivers/iio/potentiometer/max5487.c +++ b/drivers/iio/potentiometer/max5487.c @@ -83,7 +83,6 @@ static int max5487_write_raw(struct iio_dev *indio_dev, static const struct iio_info max5487_info = { .read_raw = max5487_read_raw, .write_raw = max5487_write_raw, - .driver_module = THIS_MODULE, }; static int max5487_spi_probe(struct spi_device *spi) @@ -147,7 +146,6 @@ MODULE_DEVICE_TABLE(acpi, max5487_acpi_match); static struct spi_driver max5487_driver = { .driver = { .name = "max5487", - .owner = THIS_MODULE, .acpi_match_table = ACPI_PTR(max5487_acpi_match), }, .id_table = max5487_id, diff --git a/drivers/iio/potentiometer/mcp4131.c b/drivers/iio/potentiometer/mcp4131.c index 4e7e2c6c522c..b3e30db246cc 100644 --- a/drivers/iio/potentiometer/mcp4131.c +++ b/drivers/iio/potentiometer/mcp4131.c @@ -237,7 +237,6 @@ static int mcp4131_write_raw(struct iio_dev *indio_dev, static const struct iio_info mcp4131_info = { .read_raw = mcp4131_read_raw, .write_raw = mcp4131_write_raw, - .driver_module = THIS_MODULE, }; static int mcp4131_probe(struct spi_device *spi) diff --git a/drivers/iio/potentiometer/mcp4531.c b/drivers/iio/potentiometer/mcp4531.c index 314353d7ab59..114ab876fcc6 100644 --- a/drivers/iio/potentiometer/mcp4531.c +++ b/drivers/iio/potentiometer/mcp4531.c @@ -207,7 +207,6 @@ static const struct iio_info mcp4531_info = { .read_raw = mcp4531_read_raw, .read_avail = mcp4531_read_avail, .write_raw = mcp4531_write_raw, - .driver_module = THIS_MODULE, }; #ifdef CONFIG_OF diff --git a/drivers/iio/potentiometer/tpl0102.c b/drivers/iio/potentiometer/tpl0102.c index 7b6b54531ea2..93f9d4a8c9aa 100644 --- a/drivers/iio/potentiometer/tpl0102.c +++ b/drivers/iio/potentiometer/tpl0102.c @@ -106,7 +106,6 @@ static int tpl0102_write_raw(struct iio_dev *indio_dev, static const struct iio_info tpl0102_info = { .read_raw = tpl0102_read_raw, .write_raw = tpl0102_write_raw, - .driver_module = THIS_MODULE, }; static int tpl0102_probe(struct i2c_client *client, diff --git a/drivers/iio/potentiostat/lmp91000.c b/drivers/iio/potentiostat/lmp91000.c index afa8de3418d0..007710991f15 100644 --- a/drivers/iio/potentiostat/lmp91000.c +++ b/drivers/iio/potentiostat/lmp91000.c @@ -207,7 +207,6 @@ static int lmp91000_read_raw(struct iio_dev *indio_dev, } static const struct iio_info lmp91000_info = { - .driver_module = THIS_MODULE, .read_raw = lmp91000_read_raw, }; @@ -283,7 +282,6 @@ static int lmp91000_buffer_cb(const void *val, void *private) } static const struct iio_trigger_ops lmp91000_trigger_ops = { - .owner = THIS_MODULE, }; diff --git a/drivers/iio/pressure/abp060mg.c b/drivers/iio/pressure/abp060mg.c index 43bdd0b9155f..46a220c70d6a 100644 --- a/drivers/iio/pressure/abp060mg.c +++ b/drivers/iio/pressure/abp060mg.c @@ -168,7 +168,6 @@ static int abp060mg_read_raw(struct iio_dev *indio_dev, } static const struct iio_info abp060mg_info = { - .driver_module = THIS_MODULE, .read_raw = abp060mg_read_raw, }; diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c index 8f26428804a2..fd1da26a62e4 100644 --- a/drivers/iio/pressure/bmp280-core.c +++ b/drivers/iio/pressure/bmp280-core.c @@ -561,7 +561,6 @@ static const struct attribute_group bmp280_attrs_group = { }; static const struct iio_info bmp280_info = { - .driver_module = THIS_MODULE, .read_raw = &bmp280_read_raw, .write_raw = &bmp280_write_raw, .attrs = &bmp280_attrs_group, diff --git a/drivers/iio/pressure/cros_ec_baro.c b/drivers/iio/pressure/cros_ec_baro.c index 48b2a30f57ae..4599fde4dd25 100644 --- a/drivers/iio/pressure/cros_ec_baro.c +++ b/drivers/iio/pressure/cros_ec_baro.c @@ -120,14 +120,12 @@ static int cros_ec_baro_write(struct iio_dev *indio_dev, static const struct iio_info cros_ec_baro_info = { .read_raw = &cros_ec_baro_read, .write_raw = &cros_ec_baro_write, - .driver_module = THIS_MODULE, }; static int cros_ec_baro_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct cros_ec_dev *ec_dev = dev_get_drvdata(dev->parent); - struct cros_ec_device *ec_device; struct iio_dev *indio_dev; struct cros_ec_baro_state *state; struct iio_chan_spec *channel; @@ -137,7 +135,6 @@ static int cros_ec_baro_probe(struct platform_device *pdev) dev_warn(dev, "No CROS EC device found.\n"); return -EINVAL; } - ec_device = ec_dev->ec_dev; indio_dev = devm_iio_device_alloc(dev, sizeof(*state)); if (!indio_dev) diff --git a/drivers/iio/pressure/hid-sensor-press.c b/drivers/iio/pressure/hid-sensor-press.c index 6848d8c80eff..4c437918f1d2 100644 --- a/drivers/iio/pressure/hid-sensor-press.c +++ b/drivers/iio/pressure/hid-sensor-press.c @@ -160,7 +160,6 @@ static int press_write_raw(struct iio_dev *indio_dev, } static const struct iio_info press_info = { - .driver_module = THIS_MODULE, .read_raw = &press_read_raw, .write_raw = &press_write_raw, }; diff --git a/drivers/iio/pressure/hp03.c b/drivers/iio/pressure/hp03.c index 8c7b3ec3d84a..406934ea6228 100644 --- a/drivers/iio/pressure/hp03.c +++ b/drivers/iio/pressure/hp03.c @@ -208,7 +208,6 @@ static int hp03_read_raw(struct iio_dev *indio_dev, } static const struct iio_info hp03_info = { - .driver_module = THIS_MODULE, .read_raw = &hp03_read_raw, }; diff --git a/drivers/iio/pressure/hp206c.c b/drivers/iio/pressure/hp206c.c index 12f769e86355..c38c19678cf6 100644 --- a/drivers/iio/pressure/hp206c.c +++ b/drivers/iio/pressure/hp206c.c @@ -351,7 +351,6 @@ static const struct iio_info hp206c_info = { .attrs = &hp206c_attribute_group, .read_raw = hp206c_read_raw, .write_raw = hp206c_write_raw, - .driver_module = THIS_MODULE, }; static int hp206c_probe(struct i2c_client *client, diff --git a/drivers/iio/pressure/mpl115.c b/drivers/iio/pressure/mpl115.c index 8f2bce213248..ab4786d0102b 100644 --- a/drivers/iio/pressure/mpl115.c +++ b/drivers/iio/pressure/mpl115.c @@ -144,7 +144,6 @@ static const struct iio_chan_spec mpl115_channels[] = { static const struct iio_info mpl115_info = { .read_raw = &mpl115_read_raw, - .driver_module = THIS_MODULE, }; int mpl115_probe(struct device *dev, const char *name, diff --git a/drivers/iio/pressure/mpl3115.c b/drivers/iio/pressure/mpl3115.c index 619b963714c7..7537547fb7ee 100644 --- a/drivers/iio/pressure/mpl3115.c +++ b/drivers/iio/pressure/mpl3115.c @@ -218,7 +218,6 @@ static const struct iio_chan_spec mpl3115_channels[] = { static const struct iio_info mpl3115_info = { .read_raw = &mpl3115_read_raw, - .driver_module = THIS_MODULE, }; static int mpl3115_probe(struct i2c_client *client, diff --git a/drivers/iio/pressure/ms5611_core.c b/drivers/iio/pressure/ms5611_core.c index 2a77a2f15752..f950cfde5db9 100644 --- a/drivers/iio/pressure/ms5611_core.c +++ b/drivers/iio/pressure/ms5611_core.c @@ -384,7 +384,6 @@ static const struct iio_info ms5611_info = { .read_raw = &ms5611_read_raw, .write_raw = &ms5611_write_raw, .attrs = &ms5611_attribute_group, - .driver_module = THIS_MODULE, }; static int ms5611_init(struct iio_dev *indio_dev) diff --git a/drivers/iio/pressure/ms5637.c b/drivers/iio/pressure/ms5637.c index c413f8a84a63..e2f73e6dc58f 100644 --- a/drivers/iio/pressure/ms5637.c +++ b/drivers/iio/pressure/ms5637.c @@ -124,7 +124,6 @@ static const struct iio_info ms5637_info = { .read_raw = ms5637_read_raw, .write_raw = ms5637_write_raw, .attrs = &ms5637_attribute_group, - .driver_module = THIS_MODULE, }; static int ms5637_probe(struct i2c_client *client, diff --git a/drivers/iio/pressure/st_pressure.h b/drivers/iio/pressure/st_pressure.h index 7d995937adba..e67eb0d971bf 100644 --- a/drivers/iio/pressure/st_pressure.h +++ b/drivers/iio/pressure/st_pressure.h @@ -19,6 +19,8 @@ enum st_press_type { LPS25H, LPS331AP, LPS22HB, + LPS33HW, + LPS35HW, ST_PRESS_MAX, }; @@ -26,6 +28,8 @@ enum st_press_type { #define LPS25H_PRESS_DEV_NAME "lps25h" #define LPS331AP_PRESS_DEV_NAME "lps331ap" #define LPS22HB_PRESS_DEV_NAME "lps22hb" +#define LPS33HW_PRESS_DEV_NAME "lps33hw" +#define LPS35HW_PRESS_DEV_NAME "lps35hw" /** * struct st_sensors_platform_data - default press platform data diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c index 34611a8ea2ce..349e5c713c03 100644 --- a/drivers/iio/pressure/st_pressure_core.c +++ b/drivers/iio/pressure/st_pressure_core.c @@ -280,14 +280,28 @@ static const struct st_sensor_settings st_press_sensors_settings[] = { .mask = 0x04, }, .drdy_irq = { - .addr = 0x22, - .mask_int1 = 0x04, - .mask_int2 = 0x20, + .int1 = { + .addr = 0x22, + .mask = 0x04, + .addr_od = 0x22, + .mask_od = 0x40, + }, + .int2 = { + .addr = 0x22, + .mask = 0x20, + .addr_od = 0x22, + .mask_od = 0x40, + }, .addr_ihl = 0x22, .mask_ihl = 0x80, - .addr_od = 0x22, - .mask_od = 0x40, - .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR, + .stat_drdy = { + .addr = ST_SENSORS_DEFAULT_STAT_ADDR, + .mask = 0x03, + }, + }, + .sim = { + .addr = 0x20, + .value = BIT(0), }, .multi_read_bit = true, .bootime = 2, @@ -335,8 +349,9 @@ static const struct st_sensor_settings st_press_sensors_settings[] = { .addr = 0x20, .mask = 0x04, }, - .drdy_irq = { - .addr = 0, + .sim = { + .addr = 0x20, + .value = BIT(0), }, .multi_read_bit = true, .bootime = 2, @@ -388,14 +403,22 @@ static const struct st_sensor_settings st_press_sensors_settings[] = { .mask = 0x04, }, .drdy_irq = { - .addr = 0x23, - .mask_int1 = 0x01, - .mask_int2 = 0x00, + .int1 = { + .addr = 0x23, + .mask = 0x01, + .addr_od = 0x22, + .mask_od = 0x40, + }, .addr_ihl = 0x22, .mask_ihl = 0x80, - .addr_od = 0x22, - .mask_od = 0x40, - .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR, + .stat_drdy = { + .addr = ST_SENSORS_DEFAULT_STAT_ADDR, + .mask = 0x03, + }, + }, + .sim = { + .addr = 0x20, + .value = BIT(0), }, .multi_read_bit = true, .bootime = 2, @@ -410,6 +433,8 @@ static const struct st_sensor_settings st_press_sensors_settings[] = { .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS, .sensors_supported = { [0] = LPS22HB_PRESS_DEV_NAME, + [1] = LPS33HW_PRESS_DEV_NAME, + [2] = LPS35HW_PRESS_DEV_NAME, }, .ch = (struct iio_chan_spec *)st_press_lps22hb_channels, .num_ch = ARRAY_SIZE(st_press_lps22hb_channels), @@ -447,14 +472,22 @@ static const struct st_sensor_settings st_press_sensors_settings[] = { .mask = 0x02, }, .drdy_irq = { - .addr = 0x12, - .mask_int1 = 0x04, - .mask_int2 = 0x00, + .int1 = { + .addr = 0x12, + .mask = 0x04, + .addr_od = 0x12, + .mask_od = 0x40, + }, .addr_ihl = 0x12, .mask_ihl = 0x80, - .addr_od = 0x12, - .mask_od = 0x40, - .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR, + .stat_drdy = { + .addr = ST_SENSORS_DEFAULT_STAT_ADDR, + .mask = 0x03, + }, + }, + .sim = { + .addr = 0x10, + .value = BIT(0), }, .multi_read_bit = false, .bootime = 2, @@ -547,7 +580,6 @@ static const struct attribute_group st_press_attribute_group = { }; static const struct iio_info press_info = { - .driver_module = THIS_MODULE, .attrs = &st_press_attribute_group, .read_raw = &st_press_read_raw, .write_raw = &st_press_write_raw, @@ -556,7 +588,6 @@ static const struct iio_info press_info = { #ifdef CONFIG_IIO_TRIGGER static const struct iio_trigger_ops st_press_trigger_ops = { - .owner = THIS_MODULE, .set_trigger_state = ST_PRESS_TRIGGER_SET_STATE, .validate_device = st_sensors_validate_device, }; @@ -605,7 +636,8 @@ int st_press_common_probe(struct iio_dev *indio_dev) press_data->odr = press_data->sensor_settings->odr.odr_avl[0].hz; /* Some devices don't support a data ready pin. */ - if (!pdata && press_data->sensor_settings->drdy_irq.addr) + if (!pdata && (press_data->sensor_settings->drdy_irq.int1.addr || + press_data->sensor_settings->drdy_irq.int2.addr)) pdata = (struct st_sensors_platform_data *)&default_press_pdata; err = st_sensors_init_sensor(indio_dev, press_data->dev->platform_data); diff --git a/drivers/iio/pressure/st_pressure_i2c.c b/drivers/iio/pressure/st_pressure_i2c.c index 7f15e927fa2b..fbb59059e942 100644 --- a/drivers/iio/pressure/st_pressure_i2c.c +++ b/drivers/iio/pressure/st_pressure_i2c.c @@ -37,6 +37,14 @@ static const struct of_device_id st_press_of_match[] = { .compatible = "st,lps22hb-press", .data = LPS22HB_PRESS_DEV_NAME, }, + { + .compatible = "st,lps33hw", + .data = LPS33HW_PRESS_DEV_NAME, + }, + { + .compatible = "st,lps35hw", + .data = LPS35HW_PRESS_DEV_NAME, + }, {}, }; MODULE_DEVICE_TABLE(of, st_press_of_match); @@ -59,6 +67,8 @@ static const struct i2c_device_id st_press_id_table[] = { { LPS25H_PRESS_DEV_NAME, LPS25H }, { LPS331AP_PRESS_DEV_NAME, LPS331AP }, { LPS22HB_PRESS_DEV_NAME, LPS22HB }, + { LPS33HW_PRESS_DEV_NAME, LPS33HW }, + { LPS35HW_PRESS_DEV_NAME, LPS35HW }, {}, }; MODULE_DEVICE_TABLE(i2c, st_press_id_table); diff --git a/drivers/iio/pressure/st_pressure_spi.c b/drivers/iio/pressure/st_pressure_spi.c index f5ebd36bb4bf..9a3441b128e7 100644 --- a/drivers/iio/pressure/st_pressure_spi.c +++ b/drivers/iio/pressure/st_pressure_spi.c @@ -41,6 +41,14 @@ static const struct of_device_id st_press_of_match[] = { .compatible = "st,lps22hb-press", .data = LPS22HB_PRESS_DEV_NAME, }, + { + .compatible = "st,lps33hw", + .data = LPS33HW_PRESS_DEV_NAME, + }, + { + .compatible = "st,lps35hw", + .data = LPS35HW_PRESS_DEV_NAME, + }, {}, }; MODULE_DEVICE_TABLE(of, st_press_of_match); @@ -83,6 +91,8 @@ static const struct spi_device_id st_press_id_table[] = { { LPS25H_PRESS_DEV_NAME }, { LPS331AP_PRESS_DEV_NAME }, { LPS22HB_PRESS_DEV_NAME }, + { LPS33HW_PRESS_DEV_NAME }, + { LPS35HW_PRESS_DEV_NAME }, {}, }; MODULE_DEVICE_TABLE(spi, st_press_id_table); diff --git a/drivers/iio/pressure/t5403.c b/drivers/iio/pressure/t5403.c index 2667e71721f5..92c00f603b1d 100644 --- a/drivers/iio/pressure/t5403.c +++ b/drivers/iio/pressure/t5403.c @@ -209,7 +209,6 @@ static const struct iio_info t5403_info = { .read_raw = &t5403_read_raw, .write_raw = &t5403_write_raw, .attrs = &t5403_attribute_group, - .driver_module = THIS_MODULE, }; static int t5403_probe(struct i2c_client *client, diff --git a/drivers/iio/pressure/zpa2326.c b/drivers/iio/pressure/zpa2326.c index 91431454eb85..81d8f24eaeb4 100644 --- a/drivers/iio/pressure/zpa2326.c +++ b/drivers/iio/pressure/zpa2326.c @@ -1390,7 +1390,6 @@ static int zpa2326_set_trigger_state(struct iio_trigger *trig, bool state) } static const struct iio_trigger_ops zpa2326_trigger_ops = { - .owner = THIS_MODULE, .set_trigger_state = zpa2326_set_trigger_state, }; @@ -1590,7 +1589,6 @@ static const struct iio_chan_spec zpa2326_channels[] = { }; static const struct iio_info zpa2326_info = { - .driver_module = THIS_MODULE, .attrs = &zpa2326_attribute_group, .read_raw = zpa2326_read_raw, .write_raw = zpa2326_write_raw, diff --git a/drivers/iio/proximity/Kconfig b/drivers/iio/proximity/Kconfig index ae070950f920..fcb1c4ba5e41 100644 --- a/drivers/iio/proximity/Kconfig +++ b/drivers/iio/proximity/Kconfig @@ -32,6 +32,16 @@ config LIDAR_LITE_V2 To compile this driver as a module, choose M here: the module will be called pulsedlight-lite-v2 +config RFD77402 + tristate "RFD77402 ToF sensor" + depends on I2C + help + Say Y to build a driver for the RFD77420 Time-of-Flight (distance) + sensor module with I2C interface. + + To compile this driver as a module, choose M here: the + module will be called rfd77402. + config SRF04 tristate "Devantech SRF04 ultrasonic ranger sensor" depends on GPIOLIB diff --git a/drivers/iio/proximity/Makefile b/drivers/iio/proximity/Makefile index ad6686391f08..4f4ed45e87ef 100644 --- a/drivers/iio/proximity/Makefile +++ b/drivers/iio/proximity/Makefile @@ -6,6 +6,7 @@ # When adding new entries keep the list in alphabetical order obj-$(CONFIG_AS3935) += as3935.o obj-$(CONFIG_LIDAR_LITE_V2) += pulsedlight-lidar-lite-v2.o +obj-$(CONFIG_RFD77402) += rfd77402.o obj-$(CONFIG_SRF04) += srf04.o obj-$(CONFIG_SRF08) += srf08.o obj-$(CONFIG_SX9500) += sx9500.o diff --git a/drivers/iio/proximity/as3935.c b/drivers/iio/proximity/as3935.c index 4a48b7ba3a1c..b6249af48014 100644 --- a/drivers/iio/proximity/as3935.c +++ b/drivers/iio/proximity/as3935.c @@ -221,7 +221,6 @@ static int as3935_read_raw(struct iio_dev *indio_dev, } static const struct iio_info as3935_info = { - .driver_module = THIS_MODULE, .attrs = &as3935_attribute_group, .read_raw = &as3935_read_raw, }; @@ -247,7 +246,6 @@ err_read: } static const struct iio_trigger_ops iio_interrupt_trigger_ops = { - .owner = THIS_MODULE, }; static void as3935_event_work(struct work_struct *work) diff --git a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c index 36c1ddc251aa..4d56f67b24c6 100644 --- a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c +++ b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c @@ -249,7 +249,6 @@ static irqreturn_t lidar_trigger_handler(int irq, void *private) } static const struct iio_info lidar_info = { - .driver_module = THIS_MODULE, .read_raw = lidar_read_raw, }; diff --git a/drivers/iio/proximity/rfd77402.c b/drivers/iio/proximity/rfd77402.c new file mode 100644 index 000000000000..fe29fb1a19a6 --- /dev/null +++ b/drivers/iio/proximity/rfd77402.c @@ -0,0 +1,352 @@ +/* + * rfd77402.c - Support for RF Digital RFD77402 Time-of-Flight (distance) sensor + * + * Copyright 2017 Peter Meerwald-Stadler <pmeerw@pmeerw.net> + * + * This file is subject to the terms and conditions of version 2 of + * the GNU General Public License. See the file COPYING in the main + * directory of this archive for more details. + * + * 7-bit I2C slave address 0x4c + * + * TODO: interrupt + * https://media.digikey.com/pdf/Data%20Sheets/RF%20Digital%20PDFs/RFD77402.pdf + */ + +#include <linux/module.h> +#include <linux/i2c.h> +#include <linux/delay.h> + +#include <linux/iio/iio.h> + +#define RFD77402_DRV_NAME "rfd77402" + +#define RFD77402_ICSR 0x00 /* Interrupt Control Status Register */ +#define RFD77402_ICSR_INT_MODE BIT(2) +#define RFD77402_ICSR_INT_POL BIT(3) +#define RFD77402_ICSR_RESULT BIT(4) +#define RFD77402_ICSR_M2H_MSG BIT(5) +#define RFD77402_ICSR_H2M_MSG BIT(6) +#define RFD77402_ICSR_RESET BIT(7) + +#define RFD77402_CMD_R 0x04 +#define RFD77402_CMD_SINGLE 0x01 +#define RFD77402_CMD_STANDBY 0x10 +#define RFD77402_CMD_MCPU_OFF 0x11 +#define RFD77402_CMD_MCPU_ON 0x12 +#define RFD77402_CMD_RESET BIT(6) +#define RFD77402_CMD_VALID BIT(7) + +#define RFD77402_STATUS_R 0x06 +#define RFD77402_STATUS_PM_MASK GENMASK(4, 0) +#define RFD77402_STATUS_STANDBY 0x00 +#define RFD77402_STATUS_MCPU_OFF 0x10 +#define RFD77402_STATUS_MCPU_ON 0x18 + +#define RFD77402_RESULT_R 0x08 +#define RFD77402_RESULT_DIST_MASK GENMASK(12, 2) +#define RFD77402_RESULT_ERR_MASK GENMASK(14, 13) +#define RFD77402_RESULT_VALID BIT(15) + +#define RFD77402_PMU_CFG 0x14 +#define RFD77402_PMU_MCPU_INIT BIT(9) + +#define RFD77402_I2C_INIT_CFG 0x1c +#define RFD77402_I2C_ADDR_INCR BIT(0) +#define RFD77402_I2C_DATA_INCR BIT(2) +#define RFD77402_I2C_HOST_DEBUG BIT(5) +#define RFD77402_I2C_MCPU_DEBUG BIT(6) + +#define RFD77402_CMD_CFGR_A 0x0c +#define RFD77402_CMD_CFGR_B 0x0e +#define RFD77402_HFCFG_0 0x20 +#define RFD77402_HFCFG_1 0x22 +#define RFD77402_HFCFG_2 0x24 +#define RFD77402_HFCFG_3 0x26 + +#define RFD77402_MOD_CHIP_ID 0x28 + +/* magic configuration values from datasheet */ +static const struct { + u8 reg; + u16 val; +} rf77402_tof_config[] = { + {RFD77402_CMD_CFGR_A, 0xe100}, + {RFD77402_CMD_CFGR_B, 0x10ff}, + {RFD77402_HFCFG_0, 0x07d0}, + {RFD77402_HFCFG_1, 0x5008}, + {RFD77402_HFCFG_2, 0xa041}, + {RFD77402_HFCFG_3, 0x45d4}, +}; + +struct rfd77402_data { + struct i2c_client *client; + /* Serialize reads from the sensor */ + struct mutex lock; +}; + +static const struct iio_chan_spec rfd77402_channels[] = { + { + .type = IIO_DISTANCE, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), + }, +}; + +static int rfd77402_set_state(struct rfd77402_data *data, u8 state, u16 check) +{ + int ret; + + ret = i2c_smbus_write_byte_data(data->client, RFD77402_CMD_R, + state | RFD77402_CMD_VALID); + if (ret < 0) + return ret; + + usleep_range(10000, 20000); + + ret = i2c_smbus_read_word_data(data->client, RFD77402_STATUS_R); + if (ret < 0) + return ret; + if ((ret & RFD77402_STATUS_PM_MASK) != check) + return -ENODEV; + + return 0; +} + +static int rfd77402_measure(struct rfd77402_data *data) +{ + int ret; + int tries = 10; + + ret = rfd77402_set_state(data, RFD77402_CMD_MCPU_ON, + RFD77402_STATUS_MCPU_ON); + if (ret < 0) + return ret; + + ret = i2c_smbus_write_byte_data(data->client, RFD77402_CMD_R, + RFD77402_CMD_SINGLE | + RFD77402_CMD_VALID); + if (ret < 0) + goto err; + + while (tries-- > 0) { + ret = i2c_smbus_read_byte_data(data->client, RFD77402_ICSR); + if (ret < 0) + goto err; + if (ret & RFD77402_ICSR_RESULT) + break; + msleep(20); + } + + if (tries < 0) { + ret = -ETIMEDOUT; + goto err; + } + + ret = i2c_smbus_read_word_data(data->client, RFD77402_RESULT_R); + if (ret < 0) + goto err; + + if ((ret & RFD77402_RESULT_ERR_MASK) || + !(ret & RFD77402_RESULT_VALID)) { + ret = -EIO; + goto err; + } + + return (ret & RFD77402_RESULT_DIST_MASK) >> 2; + +err: + rfd77402_set_state(data, RFD77402_CMD_MCPU_OFF, + RFD77402_STATUS_MCPU_OFF); + return ret; +} + +static int rfd77402_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct rfd77402_data *data = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + mutex_lock(&data->lock); + ret = rfd77402_measure(data); + mutex_unlock(&data->lock); + if (ret < 0) + return ret; + *val = ret; + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + /* 1 LSB is 1 mm */ + *val = 0; + *val2 = 1000; + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } +} + +static const struct iio_info rfd77402_info = { + .read_raw = rfd77402_read_raw, +}; + +static int rfd77402_init(struct rfd77402_data *data) +{ + int ret, i; + + ret = rfd77402_set_state(data, RFD77402_CMD_STANDBY, + RFD77402_STATUS_STANDBY); + if (ret < 0) + return ret; + + /* configure INT pad as push-pull, active low */ + ret = i2c_smbus_write_byte_data(data->client, RFD77402_ICSR, + RFD77402_ICSR_INT_MODE); + if (ret < 0) + return ret; + + /* I2C configuration */ + ret = i2c_smbus_write_word_data(data->client, RFD77402_I2C_INIT_CFG, + RFD77402_I2C_ADDR_INCR | + RFD77402_I2C_DATA_INCR | + RFD77402_I2C_HOST_DEBUG | + RFD77402_I2C_MCPU_DEBUG); + if (ret < 0) + return ret; + + /* set initialization */ + ret = i2c_smbus_write_word_data(data->client, RFD77402_PMU_CFG, 0x0500); + if (ret < 0) + return ret; + + ret = rfd77402_set_state(data, RFD77402_CMD_MCPU_OFF, + RFD77402_STATUS_MCPU_OFF); + if (ret < 0) + return ret; + + /* set initialization */ + ret = i2c_smbus_write_word_data(data->client, RFD77402_PMU_CFG, 0x0600); + if (ret < 0) + return ret; + + ret = rfd77402_set_state(data, RFD77402_CMD_MCPU_ON, + RFD77402_STATUS_MCPU_ON); + if (ret < 0) + return ret; + + for (i = 0; i < ARRAY_SIZE(rf77402_tof_config); i++) { + ret = i2c_smbus_write_word_data(data->client, + rf77402_tof_config[i].reg, + rf77402_tof_config[i].val); + if (ret < 0) + return ret; + } + + ret = rfd77402_set_state(data, RFD77402_CMD_STANDBY, + RFD77402_STATUS_STANDBY); + + return ret; +} + +static int rfd77402_powerdown(struct rfd77402_data *data) +{ + return rfd77402_set_state(data, RFD77402_CMD_STANDBY, + RFD77402_STATUS_STANDBY); +} + +static int rfd77402_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct rfd77402_data *data; + struct iio_dev *indio_dev; + int ret; + + ret = i2c_smbus_read_word_data(client, RFD77402_MOD_CHIP_ID); + if (ret < 0) + return ret; + if (ret != 0xad01 && ret != 0xad02) /* known chip ids */ + return -ENODEV; + + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + data = iio_priv(indio_dev); + i2c_set_clientdata(client, indio_dev); + data->client = client; + mutex_init(&data->lock); + + indio_dev->dev.parent = &client->dev; + indio_dev->info = &rfd77402_info; + indio_dev->channels = rfd77402_channels; + indio_dev->num_channels = ARRAY_SIZE(rfd77402_channels); + indio_dev->name = RFD77402_DRV_NAME; + indio_dev->modes = INDIO_DIRECT_MODE; + + ret = rfd77402_init(data); + if (ret < 0) + return ret; + + ret = iio_device_register(indio_dev); + if (ret) + goto err_powerdown; + + return 0; + +err_powerdown: + rfd77402_powerdown(data); + return ret; +} + +static int rfd77402_remove(struct i2c_client *client) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(client); + + iio_device_unregister(indio_dev); + rfd77402_powerdown(iio_priv(indio_dev)); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int rfd77402_suspend(struct device *dev) +{ + struct rfd77402_data *data = iio_priv(i2c_get_clientdata( + to_i2c_client(dev))); + + return rfd77402_powerdown(data); +} + +static int rfd77402_resume(struct device *dev) +{ + struct rfd77402_data *data = iio_priv(i2c_get_clientdata( + to_i2c_client(dev))); + + return rfd77402_init(data); +} +#endif + +static SIMPLE_DEV_PM_OPS(rfd77402_pm_ops, rfd77402_suspend, rfd77402_resume); + +static const struct i2c_device_id rfd77402_id[] = { + { "rfd77402", 0}, + { } +}; +MODULE_DEVICE_TABLE(i2c, rfd77402_id); + +static struct i2c_driver rfd77402_driver = { + .driver = { + .name = RFD77402_DRV_NAME, + .pm = &rfd77402_pm_ops, + }, + .probe = rfd77402_probe, + .remove = rfd77402_remove, + .id_table = rfd77402_id, +}; + +module_i2c_driver(rfd77402_driver); + +MODULE_AUTHOR("Peter Meerwald-Stadler <pmeerw@pmeerw.net>"); +MODULE_DESCRIPTION("RFD77402 Time-of-Flight sensor driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/proximity/srf04.c b/drivers/iio/proximity/srf04.c index e37667f933b3..09c7b9c095b0 100644 --- a/drivers/iio/proximity/srf04.c +++ b/drivers/iio/proximity/srf04.c @@ -203,7 +203,6 @@ static int srf04_read_raw(struct iio_dev *indio_dev, } static const struct iio_info srf04_iio_info = { - .driver_module = THIS_MODULE, .read_raw = srf04_read_raw, }; diff --git a/drivers/iio/proximity/srf08.c b/drivers/iio/proximity/srf08.c index 9380d545aab1..f2bf783f829a 100644 --- a/drivers/iio/proximity/srf08.c +++ b/drivers/iio/proximity/srf08.c @@ -436,7 +436,6 @@ static const struct iio_chan_spec srf08_channels[] = { static const struct iio_info srf08_info = { .read_raw = srf08_read_raw, .attrs = &srf08_attribute_group, - .driver_module = THIS_MODULE, }; /* @@ -445,7 +444,6 @@ static const struct iio_info srf08_info = { */ static const struct iio_info srf02_info = { .read_raw = srf08_read_raw, - .driver_module = THIS_MODULE, }; static int srf08_probe(struct i2c_client *client, diff --git a/drivers/iio/proximity/sx9500.c b/drivers/iio/proximity/sx9500.c index f42b3a1c75ff..53c5d653e780 100644 --- a/drivers/iio/proximity/sx9500.c +++ b/drivers/iio/proximity/sx9500.c @@ -615,7 +615,6 @@ static const struct attribute_group sx9500_attribute_group = { }; static const struct iio_info sx9500_info = { - .driver_module = THIS_MODULE, .attrs = &sx9500_attribute_group, .read_raw = &sx9500_read_raw, .write_raw = &sx9500_write_raw, @@ -650,7 +649,6 @@ out: static const struct iio_trigger_ops sx9500_trigger_ops = { .set_trigger_state = sx9500_set_trigger_state, - .owner = THIS_MODULE, }; static irqreturn_t sx9500_trigger_handler(int irq, void *private) diff --git a/drivers/iio/temperature/hid-sensor-temperature.c b/drivers/iio/temperature/hid-sensor-temperature.c index c01efeca4002..beaf6fd3e337 100644 --- a/drivers/iio/temperature/hid-sensor-temperature.c +++ b/drivers/iio/temperature/hid-sensor-temperature.c @@ -123,7 +123,6 @@ static int temperature_write_raw(struct iio_dev *indio_dev, } static const struct iio_info temperature_info = { - .driver_module = THIS_MODULE, .read_raw = &temperature_read_raw, .write_raw = &temperature_write_raw, }; diff --git a/drivers/iio/temperature/maxim_thermocouple.c b/drivers/iio/temperature/maxim_thermocouple.c index d70e2e53d6a7..e8b7e0b6c8ad 100644 --- a/drivers/iio/temperature/maxim_thermocouple.c +++ b/drivers/iio/temperature/maxim_thermocouple.c @@ -208,7 +208,6 @@ static int maxim_thermocouple_read_raw(struct iio_dev *indio_dev, } static const struct iio_info maxim_thermocouple_info = { - .driver_module = THIS_MODULE, .read_raw = maxim_thermocouple_read_raw, }; diff --git a/drivers/iio/temperature/mlx90614.c b/drivers/iio/temperature/mlx90614.c index 2077eef4095c..d619e8634a00 100644 --- a/drivers/iio/temperature/mlx90614.c +++ b/drivers/iio/temperature/mlx90614.c @@ -400,7 +400,6 @@ static const struct iio_info mlx90614_info = { .write_raw = mlx90614_write_raw, .write_raw_get_fmt = mlx90614_write_raw_get_fmt, .attrs = &mlx90614_attr_group, - .driver_module = THIS_MODULE, }; #ifdef CONFIG_PM diff --git a/drivers/iio/temperature/tmp006.c b/drivers/iio/temperature/tmp006.c index 18c9b43c02cb..a9b5b7cc7836 100644 --- a/drivers/iio/temperature/tmp006.c +++ b/drivers/iio/temperature/tmp006.c @@ -179,7 +179,6 @@ static const struct iio_info tmp006_info = { .read_raw = tmp006_read_raw, .write_raw = tmp006_write_raw, .attrs = &tmp006_attribute_group, - .driver_module = THIS_MODULE, }; static bool tmp006_check_identification(struct i2c_client *client) diff --git a/drivers/iio/temperature/tmp007.c b/drivers/iio/temperature/tmp007.c index 0615324d054c..0e3f2d432e10 100644 --- a/drivers/iio/temperature/tmp007.c +++ b/drivers/iio/temperature/tmp007.c @@ -426,7 +426,6 @@ static const struct iio_info tmp007_info = { .read_event_value = tmp007_read_thresh, .write_event_value = tmp007_write_thresh, .attrs = &tmp007_attribute_group, - .driver_module = THIS_MODULE, }; static bool tmp007_identify(struct i2c_client *client) diff --git a/drivers/iio/temperature/tsys01.c b/drivers/iio/temperature/tsys01.c index d8aa211d76e4..3799d007c8e7 100644 --- a/drivers/iio/temperature/tsys01.c +++ b/drivers/iio/temperature/tsys01.c @@ -111,7 +111,6 @@ static const struct iio_chan_spec tsys01_channels[] = { static const struct iio_info tsys01_info = { .read_raw = tsys01_read_raw, - .driver_module = THIS_MODULE, }; static bool tsys01_crc_valid(u16 *n_prom) diff --git a/drivers/iio/temperature/tsys02d.c b/drivers/iio/temperature/tsys02d.c index c0a19a000387..9b2e56fa5fd5 100644 --- a/drivers/iio/temperature/tsys02d.c +++ b/drivers/iio/temperature/tsys02d.c @@ -120,7 +120,6 @@ static const struct iio_info tsys02d_info = { .read_raw = tsys02d_read_raw, .write_raw = tsys02d_write_raw, .attrs = &tsys02d_attribute_group, - .driver_module = THIS_MODULE, }; static int tsys02d_probe(struct i2c_client *client, diff --git a/drivers/iio/trigger/iio-trig-hrtimer.c b/drivers/iio/trigger/iio-trig-hrtimer.c index a1cad6cc2e0f..7accd0187ba1 100644 --- a/drivers/iio/trigger/iio-trig-hrtimer.c +++ b/drivers/iio/trigger/iio-trig-hrtimer.c @@ -30,7 +30,7 @@ struct iio_hrtimer_info { ktime_t period; }; -static struct config_item_type iio_hrtimer_type = { +static const struct config_item_type iio_hrtimer_type = { .ct_owner = THIS_MODULE, }; @@ -114,7 +114,6 @@ static int iio_trig_hrtimer_set_state(struct iio_trigger *trig, bool state) } static const struct iio_trigger_ops iio_hrtimer_trigger_ops = { - .owner = THIS_MODULE, .set_trigger_state = iio_trig_hrtimer_set_state, }; diff --git a/drivers/iio/trigger/iio-trig-interrupt.c b/drivers/iio/trigger/iio-trig-interrupt.c index e18f12b74610..171c4ed03543 100644 --- a/drivers/iio/trigger/iio-trig-interrupt.c +++ b/drivers/iio/trigger/iio-trig-interrupt.c @@ -29,7 +29,6 @@ static irqreturn_t iio_interrupt_trigger_poll(int irq, void *private) } static const struct iio_trigger_ops iio_interrupt_trigger_ops = { - .owner = THIS_MODULE, }; static int iio_interrupt_trigger_probe(struct platform_device *pdev) diff --git a/drivers/iio/trigger/iio-trig-loop.c b/drivers/iio/trigger/iio-trig-loop.c index dc6be28f96fe..94a90e0a3fdb 100644 --- a/drivers/iio/trigger/iio-trig-loop.c +++ b/drivers/iio/trigger/iio-trig-loop.c @@ -36,7 +36,7 @@ struct iio_loop_info { struct task_struct *task; }; -static struct config_item_type iio_loop_type = { +static const struct config_item_type iio_loop_type = { .ct_owner = THIS_MODULE, }; @@ -74,7 +74,6 @@ static int iio_loop_trigger_set_state(struct iio_trigger *trig, bool state) static const struct iio_trigger_ops iio_loop_trigger_ops = { .set_trigger_state = iio_loop_trigger_set_state, - .owner = THIS_MODULE, }; static struct iio_sw_trigger *iio_trig_loop_probe(const char *name) diff --git a/drivers/iio/trigger/iio-trig-sysfs.c b/drivers/iio/trigger/iio-trig-sysfs.c index 202e8b89caf2..3f0dc9a1a514 100644 --- a/drivers/iio/trigger/iio-trig-sysfs.c +++ b/drivers/iio/trigger/iio-trig-sysfs.c @@ -127,7 +127,6 @@ static const struct attribute_group *iio_sysfs_trigger_attr_groups[] = { }; static const struct iio_trigger_ops iio_sysfs_trigger_ops = { - .owner = THIS_MODULE, }; static int iio_sysfs_trigger_probe(int id) diff --git a/drivers/iio/trigger/stm32-lptimer-trigger.c b/drivers/iio/trigger/stm32-lptimer-trigger.c index 241eae6a4306..de361d879929 100644 --- a/drivers/iio/trigger/stm32-lptimer-trigger.c +++ b/drivers/iio/trigger/stm32-lptimer-trigger.c @@ -37,7 +37,6 @@ static int stm32_lptim_validate_device(struct iio_trigger *trig, } static const struct iio_trigger_ops stm32_lptim_trigger_ops = { - .owner = THIS_MODULE, .validate_device = stm32_lptim_validate_device, }; diff --git a/drivers/iio/trigger/stm32-timer-trigger.c b/drivers/iio/trigger/stm32-timer-trigger.c index eb212f8c8879..b542dc484969 100644 --- a/drivers/iio/trigger/stm32-timer-trigger.c +++ b/drivers/iio/trigger/stm32-timer-trigger.c @@ -355,7 +355,6 @@ static const struct attribute_group *stm32_trigger_attr_groups[] = { }; static const struct iio_trigger_ops timer_trigger_ops = { - .owner = THIS_MODULE, }; static int stm32_setup_iio_triggers(struct stm32_timer_trigger *priv) @@ -493,7 +492,6 @@ static int stm32_counter_validate_trigger(struct iio_dev *indio_dev, } static const struct iio_info stm32_trigger_info = { - .driver_module = THIS_MODULE, .validate_trigger = stm32_counter_validate_trigger, .read_raw = stm32_counter_read_raw, .write_raw = stm32_counter_write_raw |