aboutsummaryrefslogtreecommitdiff
path: root/drivers/staging/iio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/iio')
-rw-r--r--drivers/staging/iio/Documentation/device.txt4
-rw-r--r--drivers/staging/iio/Documentation/iio_utils.h32
-rw-r--r--drivers/staging/iio/Documentation/lsiio.c157
-rw-r--r--drivers/staging/iio/Kconfig9
-rw-r--r--drivers/staging/iio/TODO11
-rw-r--r--drivers/staging/iio/accel/adis16201_core.c17
-rw-r--r--drivers/staging/iio/accel/adis16203_core.c16
-rw-r--r--drivers/staging/iio/accel/adis16204_core.c16
-rw-r--r--drivers/staging/iio/accel/adis16209_core.c16
-rw-r--r--drivers/staging/iio/accel/adis16220_core.c27
-rw-r--r--drivers/staging/iio/accel/adis16240_core.c16
-rw-r--r--drivers/staging/iio/accel/lis3l02dq_core.c75
-rw-r--r--drivers/staging/iio/accel/lis3l02dq_ring.c14
-rw-r--r--drivers/staging/iio/accel/sca3000.h26
-rw-r--r--drivers/staging/iio/accel/sca3000_core.c237
-rw-r--r--drivers/staging/iio/accel/sca3000_ring.c21
-rw-r--r--drivers/staging/iio/adc/Kconfig30
-rw-r--r--drivers/staging/iio/adc/Makefile4
-rw-r--r--drivers/staging/iio/adc/ad7192.c15
-rw-r--r--drivers/staging/iio/adc/ad7280a.c53
-rw-r--r--drivers/staging/iio/adc/ad7291.c241
-rw-r--r--drivers/staging/iio/adc/ad7606.h6
-rw-r--r--drivers/staging/iio/adc/ad7606_core.c42
-rw-r--r--drivers/staging/iio/adc/ad7606_ring.c8
-rw-r--r--drivers/staging/iio/adc/ad7780.c37
-rw-r--r--drivers/staging/iio/adc/ad7816.c73
-rw-r--r--drivers/staging/iio/adc/ad799x.h137
-rw-r--r--drivers/staging/iio/adc/ad799x_core.c707
-rw-r--r--drivers/staging/iio/adc/ad799x_ring.c90
-rw-r--r--drivers/staging/iio/adc/lpc32xx_adc.c63
-rw-r--r--drivers/staging/iio/adc/mxs-lradc.c1316
-rw-r--r--drivers/staging/iio/adc/spear_adc.c343
-rw-r--r--drivers/staging/iio/addac/adt7316-i2c.c9
-rw-r--r--drivers/staging/iio/addac/adt7316-spi.c9
-rw-r--r--drivers/staging/iio/addac/adt7316.c150
-rw-r--r--drivers/staging/iio/addac/adt7316.h9
-rw-r--r--drivers/staging/iio/cdc/ad7150.c193
-rw-r--r--drivers/staging/iio/cdc/ad7152.c18
-rw-r--r--drivers/staging/iio/cdc/ad7746.c47
-rw-r--r--drivers/staging/iio/frequency/ad5930.c16
-rw-r--r--drivers/staging/iio/frequency/ad9832.c36
-rw-r--r--drivers/staging/iio/frequency/ad9832.h6
-rw-r--r--drivers/staging/iio/frequency/ad9834.c33
-rw-r--r--drivers/staging/iio/frequency/ad9834.h4
-rw-r--r--drivers/staging/iio/frequency/ad9850.c16
-rw-r--r--drivers/staging/iio/frequency/ad9852.c62
-rw-r--r--drivers/staging/iio/frequency/ad9910.c98
-rw-r--r--drivers/staging/iio/frequency/ad9951.c43
-rw-r--r--drivers/staging/iio/gyro/Kconfig12
-rw-r--r--drivers/staging/iio/gyro/Makefile3
-rw-r--r--drivers/staging/iio/gyro/adis16060_core.c27
-rw-r--r--drivers/staging/iio/gyro/adis16260.h98
-rw-r--r--drivers/staging/iio/gyro/adis16260_core.c427
-rw-r--r--drivers/staging/iio/gyro/adis16260_platform_data.h19
-rw-r--r--drivers/staging/iio/iio_simple_dummy.c41
-rw-r--r--drivers/staging/iio/iio_simple_dummy.h22
-rw-r--r--drivers/staging/iio/iio_simple_dummy_buffer.c17
-rw-r--r--drivers/staging/iio/iio_simple_dummy_events.c49
-rw-r--r--drivers/staging/iio/impedance-analyzer/ad5933.c44
-rw-r--r--drivers/staging/iio/light/isl29018.c48
-rw-r--r--drivers/staging/iio/light/isl29028.c13
-rw-r--r--drivers/staging/iio/light/tsl2583.c92
-rw-r--r--drivers/staging/iio/light/tsl2x7x_core.c144
-rw-r--r--drivers/staging/iio/magnetometer/Kconfig2
-rw-r--r--drivers/staging/iio/magnetometer/hmc5843.c734
-rw-r--r--drivers/staging/iio/meter/ade7753.c52
-rw-r--r--drivers/staging/iio/meter/ade7754.c53
-rw-r--r--drivers/staging/iio/meter/ade7758_core.c50
-rw-r--r--drivers/staging/iio/meter/ade7758_ring.c20
-rw-r--r--drivers/staging/iio/meter/ade7759.c51
-rw-r--r--drivers/staging/iio/meter/ade7854-i2c.c4
-rw-r--r--drivers/staging/iio/meter/ade7854-spi.c6
-rw-r--r--drivers/staging/iio/meter/ade7854.c41
-rw-r--r--drivers/staging/iio/resolver/ad2s1200.c40
-rw-r--r--drivers/staging/iio/resolver/ad2s1210.c56
-rw-r--r--drivers/staging/iio/resolver/ad2s90.c16
-rw-r--r--drivers/staging/iio/trigger/iio-trig-bfin-timer.c25
-rw-r--r--drivers/staging/iio/trigger/iio-trig-periodic-rtc.c7
78 files changed, 2699 insertions, 4122 deletions
diff --git a/drivers/staging/iio/Documentation/device.txt b/drivers/staging/iio/Documentation/device.txt
index ea08d621337..8be32e5a0af 100644
--- a/drivers/staging/iio/Documentation/device.txt
+++ b/drivers/staging/iio/Documentation/device.txt
@@ -56,7 +56,7 @@ Then fill in the following:
- indio_dev->modes:
Specify whether direct access and / or ring buffer access is supported.
-- indio_dev->ring:
+- indio_dev->buffer:
An optional associated buffer.
- indio_dev->pollfunc:
Poll function related elements. This controls what occurs when a trigger
@@ -67,7 +67,7 @@ Then fill in the following:
- indio_dev->num_channels:
How many channels are there?
-Once these are set up, a call to iio_device_register(indio_dev),
+Once these are set up, a call to iio_device_register(indio_dev)
will register the device with the iio core.
Worth noting here is that, if a ring buffer is to be used, it can be
diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h
index cf32ae099cd..a9cfc06edb0 100644
--- a/drivers/staging/iio/Documentation/iio_utils.h
+++ b/drivers/staging/iio/Documentation/iio_utils.h
@@ -77,7 +77,6 @@ struct iio_channel_info {
uint64_t mask;
unsigned be;
unsigned is_signed;
- unsigned enabled;
unsigned location;
};
@@ -319,7 +318,7 @@ inline int build_channel_array(const char *device_dir,
free(filename);
goto error_close_dir;
}
- fscanf(sysfsfp, "%u", &ret);
+ fscanf(sysfsfp, "%i", &ret);
if (ret == 1)
(*counter)++;
fclose(sysfsfp);
@@ -335,6 +334,7 @@ inline int build_channel_array(const char *device_dir,
while (ent = readdir(dp), ent != NULL) {
if (strcmp(ent->d_name + strlen(ent->d_name) - strlen("_en"),
"_en") == 0) {
+ int current_enabled = 0;
current = &(*ci_array)[count++];
ret = asprintf(&filename,
"%s/%s", scan_el_dir, ent->d_name);
@@ -350,10 +350,10 @@ inline int build_channel_array(const char *device_dir,
ret = -errno;
goto error_cleanup_array;
}
- fscanf(sysfsfp, "%u", &current->enabled);
+ fscanf(sysfsfp, "%i", &current_enabled);
fclose(sysfsfp);
- if (!current->enabled) {
+ if (!current_enabled) {
free(filename);
count--;
continue;
@@ -502,7 +502,7 @@ inline int find_type_by_name(const char *name, const char *type)
inline int _write_sysfs_int(char *filename, char *basedir, int val, int verify)
{
- int ret;
+ int ret = 0;
FILE *sysfsfp;
int test;
char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
@@ -652,3 +652,25 @@ error_free:
free(temp);
return ret;
}
+
+read_sysfs_string(const char *filename, const char *basedir, char *str)
+{
+ float ret = 0;
+ FILE *sysfsfp;
+ char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
+ if (temp == NULL) {
+ printf("Memory allocation failed");
+ return -ENOMEM;
+ }
+ sprintf(temp, "%s/%s", basedir, filename);
+ sysfsfp = fopen(temp, "r");
+ if (sysfsfp == NULL) {
+ ret = -errno;
+ goto error_free;
+ }
+ fscanf(sysfsfp, "%s\n", str);
+ fclose(sysfsfp);
+error_free:
+ free(temp);
+ return ret;
+}
diff --git a/drivers/staging/iio/Documentation/lsiio.c b/drivers/staging/iio/Documentation/lsiio.c
new file mode 100644
index 00000000000..24ae9694eb4
--- /dev/null
+++ b/drivers/staging/iio/Documentation/lsiio.c
@@ -0,0 +1,157 @@
+/*
+ * Industrial I/O utilities - lsiio.c
+ *
+ * Copyright (c) 2010 Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
+ *
+ * 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 <string.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/dir.h>
+#include "iio_utils.h"
+
+
+static enum verbosity {
+ VERBLEVEL_DEFAULT, /* 0 gives lspci behaviour */
+ VERBLEVEL_SENSORS, /* 1 lists sensors */
+} verblevel = VERBLEVEL_DEFAULT;
+
+const char *type_device = "iio:device";
+const char *type_trigger = "trigger";
+
+
+static inline int check_prefix(const char *str, const char *prefix)
+{
+ return strlen(str) > strlen(prefix) &&
+ strncmp(str, prefix, strlen(prefix)) == 0;
+}
+
+static inline int check_postfix(const char *str, const char *postfix)
+{
+ return strlen(str) > strlen(postfix) &&
+ strcmp(str + strlen(str) - strlen(postfix), postfix) == 0;
+}
+
+static int dump_channels(const char *dev_dir_name)
+{
+ DIR *dp;
+ const struct dirent *ent;
+ dp = opendir(dev_dir_name);
+ if (dp == NULL)
+ return -errno;
+ while (ent = readdir(dp), ent != NULL)
+ if (check_prefix(ent->d_name, "in_") &&
+ check_postfix(ent->d_name, "_raw")) {
+ printf(" %-10s\n", ent->d_name);
+ }
+
+ return 0;
+}
+
+static int dump_one_device(const char *dev_dir_name)
+{
+ char name[IIO_MAX_NAME_LENGTH];
+ int dev_idx;
+
+ sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_device),
+ "%i", &dev_idx);
+ read_sysfs_string("name", dev_dir_name, name);
+ printf("Device %03d: %s\n", dev_idx, name);
+
+ if (verblevel >= VERBLEVEL_SENSORS) {
+ int ret = dump_channels(dev_dir_name);
+ if (ret)
+ return ret;
+ }
+ return 0;
+}
+
+static int dump_one_trigger(const char *dev_dir_name)
+{
+ char name[IIO_MAX_NAME_LENGTH];
+ int dev_idx;
+
+ sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_trigger),
+ "%i", &dev_idx);
+ read_sysfs_string("name", dev_dir_name, name);
+ printf("Trigger %03d: %s\n", dev_idx, name);
+ return 0;
+}
+
+static void dump_devices(void)
+{
+ const struct dirent *ent;
+ int number, numstrlen;
+
+ FILE *nameFile;
+ DIR *dp;
+ char thisname[IIO_MAX_NAME_LENGTH];
+ char *filename;
+
+ dp = opendir(iio_dir);
+ if (dp == NULL) {
+ printf("No industrial I/O devices available\n");
+ return;
+ }
+
+ while (ent = readdir(dp), ent != NULL) {
+ if (check_prefix(ent->d_name, type_device)) {
+ char *dev_dir_name;
+ asprintf(&dev_dir_name, "%s%s", iio_dir, ent->d_name);
+ dump_one_device(dev_dir_name);
+ free(dev_dir_name);
+ if (verblevel >= VERBLEVEL_SENSORS)
+ printf("\n");
+ }
+ }
+ rewinddir(dp);
+ while (ent = readdir(dp), ent != NULL) {
+ if (check_prefix(ent->d_name, type_trigger)) {
+ char *dev_dir_name;
+ asprintf(&dev_dir_name, "%s%s", iio_dir, ent->d_name);
+ dump_one_trigger(dev_dir_name);
+ free(dev_dir_name);
+ }
+ }
+ closedir(dp);
+}
+
+int main(int argc, char **argv)
+{
+ int c, err = 0;
+
+ while ((c = getopt(argc, argv, "d:D:v")) != EOF) {
+ switch (c) {
+ case 'v':
+ verblevel++;
+ break;
+
+ case '?':
+ default:
+ err++;
+ break;
+ }
+ }
+ if (err || argc > optind) {
+ fprintf(stderr, "Usage: lsiio [options]...\n"
+ "List industrial I/O devices\n"
+ " -v, --verbose\n"
+ " Increase verbosity (may be given multiple times)\n"
+ );
+ exit(1);
+ }
+
+ dump_devices();
+
+ return 0;
+}
diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig
index db4d6dc0324..fa38be0982f 100644
--- a/drivers/staging/iio/Kconfig
+++ b/drivers/staging/iio/Kconfig
@@ -36,10 +36,11 @@ config IIO_SIMPLE_DUMMY_EVENTS
Add some dummy events to the simple dummy driver.
config IIO_SIMPLE_DUMMY_BUFFER
- boolean "Buffered capture support"
- depends on IIO_KFIFO_BUF
- help
- Add buffered data capture to the simple dummy driver.
+ boolean "Buffered capture support"
+ select IIO_BUFFER
+ select IIO_KFIFO_BUF
+ help
+ Add buffered data capture to the simple dummy driver.
endif # IIO_SIMPLE_DUMMY
diff --git a/drivers/staging/iio/TODO b/drivers/staging/iio/TODO
index 04c23262f8e..c22a0edd152 100644
--- a/drivers/staging/iio/TODO
+++ b/drivers/staging/iio/TODO
@@ -13,6 +13,17 @@ Would be nice
3) Expand device set. Lots of other maxim adc's have very
similar interfaces.
+MXS LRADC driver:
+This is a classic MFD device as it combines the following subdevices
+ - touchscreen controller (input subsystem related device)
+ - general purpose ADC channels
+ - battery voltage monitor (power subsystem related device)
+ - die temperature monitor (thermal management)
+
+At least the battery voltage and die temperature feature is required in-kernel
+by a driver of the SoC's battery charging unit to avoid any damage to the
+silicon and the battery.
+
TSL2561
Would be nice
1) Open question of userspace vs kernel space balance when
diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c
index ab8ec7af88b..2105576fa77 100644
--- a/drivers/staging/iio/accel/adis16201_core.c
+++ b/drivers/staging/iio/accel/adis16201_core.c
@@ -182,11 +182,10 @@ static int adis16201_probe(struct spi_device *spi)
struct iio_dev *indio_dev;
/* setup the industrialio driver allocated elements */
- indio_dev = iio_device_alloc(sizeof(*st));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (!indio_dev)
+ return -ENOMEM;
+
st = iio_priv(indio_dev);
/* this is only used for removal purposes */
spi_set_drvdata(spi, indio_dev);
@@ -201,10 +200,10 @@ static int adis16201_probe(struct spi_device *spi)
ret = adis_init(st, indio_dev, spi, &adis16201_data);
if (ret)
- goto error_free_dev;
+ return ret;
ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL);
if (ret)
- goto error_free_dev;
+ return ret;
/* Get the device into a sane initial state */
ret = adis_initial_startup(st);
@@ -218,9 +217,6 @@ static int adis16201_probe(struct spi_device *spi)
error_cleanup_buffer_trigger:
adis_cleanup_buffer_and_trigger(st, indio_dev);
-error_free_dev:
- iio_device_free(indio_dev);
-error_ret:
return ret;
}
@@ -231,7 +227,6 @@ static int adis16201_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
adis_cleanup_buffer_and_trigger(st, indio_dev);
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c
index b08ac8fdeee..409a28ed904 100644
--- a/drivers/staging/iio/accel/adis16203_core.c
+++ b/drivers/staging/iio/accel/adis16203_core.c
@@ -148,11 +148,9 @@ static int adis16203_probe(struct spi_device *spi)
struct adis *st;
/* setup the industrialio driver allocated elements */
- indio_dev = iio_device_alloc(sizeof(*st));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (!indio_dev)
+ return -ENOMEM;
st = iio_priv(indio_dev);
/* this is only used for removal purposes */
spi_set_drvdata(spi, indio_dev);
@@ -166,11 +164,11 @@ static int adis16203_probe(struct spi_device *spi)
ret = adis_init(st, indio_dev, spi, &adis16203_data);
if (ret)
- goto error_free_dev;
+ return ret;
ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL);
if (ret)
- goto error_free_dev;
+ return ret;
/* Get the device into a sane initial state */
ret = adis_initial_startup(st);
@@ -185,9 +183,6 @@ static int adis16203_probe(struct spi_device *spi)
error_cleanup_buffer_trigger:
adis_cleanup_buffer_and_trigger(st, indio_dev);
-error_free_dev:
- iio_device_free(indio_dev);
-error_ret:
return ret;
}
@@ -198,7 +193,6 @@ static int adis16203_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
adis_cleanup_buffer_and_trigger(st, indio_dev);
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c
index 792ec25a50d..b8ea76857cd 100644
--- a/drivers/staging/iio/accel/adis16204_core.c
+++ b/drivers/staging/iio/accel/adis16204_core.c
@@ -187,11 +187,9 @@ static int adis16204_probe(struct spi_device *spi)
struct iio_dev *indio_dev;
/* setup the industrialio driver allocated elements */
- indio_dev = iio_device_alloc(sizeof(*st));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (!indio_dev)
+ return -ENOMEM;
st = iio_priv(indio_dev);
/* this is only used for removal purposes */
spi_set_drvdata(spi, indio_dev);
@@ -205,11 +203,11 @@ static int adis16204_probe(struct spi_device *spi)
ret = adis_init(st, indio_dev, spi, &adis16204_data);
if (ret)
- goto error_free_dev;
+ return ret;
ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL);
if (ret)
- goto error_free_dev;
+ return ret;
/* Get the device into a sane initial state */
ret = adis_initial_startup(st);
@@ -223,9 +221,6 @@ static int adis16204_probe(struct spi_device *spi)
error_cleanup_buffer_trigger:
adis_cleanup_buffer_and_trigger(st, indio_dev);
-error_free_dev:
- iio_device_free(indio_dev);
-error_ret:
return ret;
}
@@ -236,7 +231,6 @@ static int adis16204_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
adis_cleanup_buffer_and_trigger(st, indio_dev);
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c
index 323c169d699..4492e51d888 100644
--- a/drivers/staging/iio/accel/adis16209_core.c
+++ b/drivers/staging/iio/accel/adis16209_core.c
@@ -183,11 +183,9 @@ static int adis16209_probe(struct spi_device *spi)
struct iio_dev *indio_dev;
/* setup the industrialio driver allocated elements */
- indio_dev = iio_device_alloc(sizeof(*st));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (!indio_dev)
+ return -ENOMEM;
st = iio_priv(indio_dev);
/* this is only used for removal purposes */
spi_set_drvdata(spi, indio_dev);
@@ -201,10 +199,10 @@ static int adis16209_probe(struct spi_device *spi)
ret = adis_init(st, indio_dev, spi, &adis16209_data);
if (ret)
- goto error_free_dev;
+ return ret;
ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL);
if (ret)
- goto error_free_dev;
+ return ret;
/* Get the device into a sane initial state */
ret = adis_initial_startup(st);
@@ -218,9 +216,6 @@ static int adis16209_probe(struct spi_device *spi)
error_cleanup_buffer_trigger:
adis_cleanup_buffer_and_trigger(st, indio_dev);
-error_free_dev:
- iio_device_free(indio_dev);
-error_ret:
return ret;
}
@@ -231,7 +226,6 @@ static int adis16209_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
adis_cleanup_buffer_and_trigger(st, indio_dev);
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c
index 0e72f795ed0..6f38ca95f9b 100644
--- a/drivers/staging/iio/accel/adis16220_core.c
+++ b/drivers/staging/iio/accel/adis16220_core.c
@@ -102,7 +102,6 @@ static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev,
int addr)
{
struct adis16220_state *st = iio_priv(indio_dev);
- struct spi_message msg;
struct spi_transfer xfers[] = {
{
.tx_buf = st->tx,
@@ -147,10 +146,7 @@ static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev,
}
xfers[1].len = count;
- spi_message_init(&msg);
- spi_message_add_tail(&xfers[0], &msg);
- spi_message_add_tail(&xfers[1], &msg);
- ret = spi_sync(st->adis.spi, &msg);
+ ret = spi_sync_transfer(st->adis.spi, xfers, ARRAY_SIZE(xfers));
if (ret) {
mutex_unlock(&st->buf_lock);
@@ -428,11 +424,9 @@ static int adis16220_probe(struct spi_device *spi)
struct iio_dev *indio_dev;
/* setup the industrialio driver allocated elements */
- indio_dev = iio_device_alloc(sizeof(*st));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (!indio_dev)
+ return -ENOMEM;
st = iio_priv(indio_dev);
/* this is only used for removal purposes */
@@ -445,13 +439,13 @@ static int adis16220_probe(struct spi_device *spi)
indio_dev->channels = adis16220_channels;
indio_dev->num_channels = ARRAY_SIZE(adis16220_channels);
- ret = iio_device_register(indio_dev);
+ ret = devm_iio_device_register(&spi->dev, indio_dev);
if (ret)
- goto error_free_dev;
+ return ret;
ret = sysfs_create_bin_file(&indio_dev->dev.kobj, &accel_bin);
if (ret)
- goto error_unregister_dev;
+ return ret;
ret = sysfs_create_bin_file(&indio_dev->dev.kobj, &adc1_bin);
if (ret)
@@ -476,11 +470,6 @@ error_rm_adc1_bin:
sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc1_bin);
error_rm_accel_bin:
sysfs_remove_bin_file(&indio_dev->dev.kobj, &accel_bin);
-error_unregister_dev:
- iio_device_unregister(indio_dev);
-error_free_dev:
- iio_device_free(indio_dev);
-error_ret:
return ret;
}
@@ -491,8 +480,6 @@ static int adis16220_remove(struct spi_device *spi)
sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc2_bin);
sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc1_bin);
sysfs_remove_bin_file(&indio_dev->dev.kobj, &accel_bin);
- iio_device_unregister(indio_dev);
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c
index fd1f0fd0fba..3a303a03d02 100644
--- a/drivers/staging/iio/accel/adis16240_core.c
+++ b/drivers/staging/iio/accel/adis16240_core.c
@@ -236,11 +236,9 @@ static int adis16240_probe(struct spi_device *spi)
struct iio_dev *indio_dev;
/* setup the industrialio driver allocated elements */
- indio_dev = iio_device_alloc(sizeof(*st));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (!indio_dev)
+ return -ENOMEM;
st = iio_priv(indio_dev);
/* this is only used for removal purposes */
spi_set_drvdata(spi, indio_dev);
@@ -254,10 +252,10 @@ static int adis16240_probe(struct spi_device *spi)
ret = adis_init(st, indio_dev, spi, &adis16240_data);
if (ret)
- goto error_free_dev;
+ return ret;
ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL);
if (ret)
- goto error_free_dev;
+ return ret;
/* Get the device into a sane initial state */
ret = adis_initial_startup(st);
@@ -270,9 +268,6 @@ static int adis16240_probe(struct spi_device *spi)
error_cleanup_buffer_trigger:
adis_cleanup_buffer_and_trigger(st, indio_dev);
-error_free_dev:
- iio_device_free(indio_dev);
-error_ret:
return ret;
}
@@ -283,7 +278,6 @@ static int adis16240_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
adis_cleanup_buffer_and_trigger(st, indio_dev);
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index 1bfe5d81792..898653c0927 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -190,15 +190,26 @@ static u8 lis3l02dq_axis_map[3][3] = {
};
static int lis3l02dq_read_thresh(struct iio_dev *indio_dev,
- u64 e,
- int *val)
+ 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)
{
- return lis3l02dq_read_reg_s16(indio_dev, LIS3L02DQ_REG_THS_L_ADDR, val);
+ int ret;
+
+ ret = lis3l02dq_read_reg_s16(indio_dev, LIS3L02DQ_REG_THS_L_ADDR, val);
+ if (ret)
+ return ret;
+ return IIO_VAL_INT;
}
static int lis3l02dq_write_thresh(struct iio_dev *indio_dev,
- u64 event_code,
- int val)
+ 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)
{
u16 value = val;
return lis3l02dq_spi_write_reg_s16(indio_dev,
@@ -257,6 +268,8 @@ static int lis3l02dq_read_raw(struct iio_dev *indio_dev,
ret = lis3l02dq_read_reg_s16(indio_dev, reg, val);
}
mutex_unlock(&indio_dev->mlock);
+ if (ret < 0)
+ goto error_ret;
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
*val = 0;
@@ -501,9 +514,19 @@ static irqreturn_t lis3l02dq_event_handler(int irq, void *private)
return IRQ_HANDLED;
}
-#define LIS3L02DQ_EVENT_MASK \
- (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | \
- IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING))
+static const struct iio_event_spec lis3l02dq_event[] = {
+ {
+ .type = IIO_EV_TYPE_THRESH,
+ .dir = IIO_EV_DIR_RISING,
+ .mask_separate = BIT(IIO_EV_INFO_ENABLE),
+ .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE),
+ }, {
+ .type = IIO_EV_TYPE_THRESH,
+ .dir = IIO_EV_DIR_FALLING,
+ .mask_separate = BIT(IIO_EV_INFO_ENABLE),
+ .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE),
+ }
+};
#define LIS3L02DQ_CHAN(index, mod) \
{ \
@@ -521,7 +544,8 @@ static irqreturn_t lis3l02dq_event_handler(int irq, void *private)
.realbits = 12, \
.storagebits = 16, \
}, \
- .event_mask = LIS3L02DQ_EVENT_MASK, \
+ .event_spec = lis3l02dq_event, \
+ .num_event_specs = ARRAY_SIZE(lis3l02dq_event), \
}
static const struct iio_chan_spec lis3l02dq_channels[] = {
@@ -533,14 +557,14 @@ static const struct iio_chan_spec lis3l02dq_channels[] = {
static int lis3l02dq_read_event_config(struct iio_dev *indio_dev,
- u64 event_code)
+ const struct iio_chan_spec *chan,
+ enum iio_event_type type,
+ enum iio_event_direction dir)
{
u8 val;
int ret;
- u8 mask = (1 << (IIO_EVENT_CODE_EXTRACT_MODIFIER(event_code)*2 +
- (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
- IIO_EV_DIR_RISING)));
+ u8 mask = (1 << (chan->channel2*2 + (dir == IIO_EV_DIR_RISING)));
ret = lis3l02dq_spi_read_reg_8(indio_dev,
LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
&val);
@@ -585,16 +609,16 @@ error_ret:
}
static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
- u64 event_code,
+ const struct iio_chan_spec *chan,
+ enum iio_event_type type,
+ enum iio_event_direction dir,
int state)
{
int ret = 0;
u8 val, control;
u8 currentlyset;
bool changed = false;
- u8 mask = (1 << (IIO_EVENT_CODE_EXTRACT_MODIFIER(event_code)*2 +
- (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
- IIO_EV_DIR_RISING)));
+ u8 mask = (1 << (chan->channel2*2 + (dir == IIO_EV_DIR_RISING)));
mutex_lock(&indio_dev->mlock);
/* read current control */
@@ -666,11 +690,9 @@ static int lis3l02dq_probe(struct spi_device *spi)
struct lis3l02dq_state *st;
struct iio_dev *indio_dev;
- indio_dev = iio_device_alloc(sizeof *st);
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (!indio_dev)
+ return -ENOMEM;
st = iio_priv(indio_dev);
/* this is only used for removal purposes */
spi_set_drvdata(spi, indio_dev);
@@ -688,13 +710,13 @@ static int lis3l02dq_probe(struct spi_device *spi)
ret = lis3l02dq_configure_buffer(indio_dev);
if (ret)
- goto error_free_dev;
+ return ret;
ret = iio_buffer_register(indio_dev,
lis3l02dq_channels,
ARRAY_SIZE(lis3l02dq_channels));
if (ret) {
- printk(KERN_ERR "failed to initialize the buffer\n");
+ dev_err(&spi->dev, "failed to initialize the buffer\n");
goto error_unreg_buffer_funcs;
}
@@ -734,9 +756,6 @@ error_uninitialize_buffer:
iio_buffer_unregister(indio_dev);
error_unreg_buffer_funcs:
lis3l02dq_unconfigure_buffer(indio_dev);
-error_free_dev:
- iio_device_free(indio_dev);
-error_ret:
return ret;
}
@@ -784,8 +803,6 @@ static int lis3l02dq_remove(struct spi_device *spi)
iio_buffer_unregister(indio_dev);
lis3l02dq_unconfigure_buffer(indio_dev);
- iio_device_free(indio_dev);
-
return 0;
}
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index 5b8f0f6c993..79cefe0a516 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -111,7 +111,7 @@ static int lis3l02dq_get_buffer_element(struct iio_dev *indio_dev,
u8 *buf)
{
int ret, i;
- u8 *rx_array ;
+ u8 *rx_array;
s16 *data = (s16 *)buf;
int scan_count = bitmap_weight(indio_dev->active_scan_mask,
indio_dev->masklength);
@@ -146,11 +146,7 @@ static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p)
if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
len = lis3l02dq_get_buffer_element(indio_dev, data);
- /* Guaranteed to be aligned with 8 byte boundary */
- if (indio_dev->scan_timestamp)
- *(s64 *)((u8 *)data + ALIGN(len, sizeof(s64)))
- = pf->timestamp;
- iio_push_to_buffers(indio_dev, (u8 *)data);
+ iio_push_to_buffers_with_timestamp(indio_dev, data, pf->timestamp);
kfree(data);
done:
@@ -264,8 +260,7 @@ static int lis3l02dq_trig_try_reen(struct iio_trigger *trig)
else
break;
if (i == 5)
- printk(KERN_INFO
- "Failed to clear the interrupt for lis3l02dq\n");
+ pr_info("Failed to clear the interrupt for lis3l02dq\n");
/* irq reenabled so success! */
return 0;
@@ -387,7 +382,6 @@ error_ret:
}
static const struct iio_buffer_setup_ops lis3l02dq_buffer_setup_ops = {
- .preenable = &iio_sw_buffer_preenable,
.postenable = &lis3l02dq_buffer_postenable,
.predisable = &lis3l02dq_buffer_predisable,
};
@@ -401,7 +395,7 @@ int lis3l02dq_configure_buffer(struct iio_dev *indio_dev)
if (!buffer)
return -ENOMEM;
- indio_dev->buffer = buffer;
+ iio_device_attach_buffer(indio_dev, buffer);
buffer->scan_timestamp = true;
indio_dev->setup_ops = &lis3l02dq_buffer_setup_ops;
diff --git a/drivers/staging/iio/accel/sca3000.h b/drivers/staging/iio/accel/sca3000.h
index c1016c510da..b284e5a6cac 100644
--- a/drivers/staging/iio/accel/sca3000.h
+++ b/drivers/staging/iio/accel/sca3000.h
@@ -65,7 +65,8 @@
#define SCA3000_RING_BUF_ENABLE 0x80
#define SCA3000_RING_BUF_8BIT 0x40
-/* Free fall detection triggers an interrupt if the acceleration
+/*
+ * Free fall detection triggers an interrupt if the acceleration
* is below a threshold for equivalent of 25cm drop
*/
#define SCA3000_FREE_FALL_DETECT 0x10
@@ -73,8 +74,9 @@
#define SCA3000_MEAS_MODE_OP_1 0x01
#define SCA3000_MEAS_MODE_OP_2 0x02
-/* In motion detection mode the accelerations are band pass filtered
- * (aprox 1 - 25Hz) and then a programmable threshold used to trigger
+/*
+ * In motion detection mode the accelerations are band pass filtered
+ * (approx 1 - 25Hz) and then a programmable threshold used to trigger
* and interrupt.
*/
#define SCA3000_MEAS_MODE_MOT_DET 0x03
@@ -99,8 +101,10 @@
#define SCA3000_REG_CTRL_SEL_MD_Y_TH 0x03
#define SCA3000_REG_CTRL_SEL_MD_X_TH 0x04
#define SCA3000_REG_CTRL_SEL_MD_Z_TH 0x05
-/* BE VERY CAREFUL WITH THIS, IF 3 BITS ARE NOT SET the device
- will not function */
+/*
+ * BE VERY CAREFUL WITH THIS, IF 3 BITS ARE NOT SET the device
+ * will not function
+ */
#define SCA3000_REG_CTRL_SEL_OUT_CTRL 0x0B
#define SCA3000_OUT_CTRL_PROT_MASK 0xE0
#define SCA3000_OUT_CTRL_BUF_X_EN 0x10
@@ -109,8 +113,9 @@
#define SCA3000_OUT_CTRL_BUF_DIV_4 0x02
#define SCA3000_OUT_CTRL_BUF_DIV_2 0x01
-/* Control which motion detector interrupts are on.
- * For now only OR combinations are supported.x
+/*
+ * Control which motion detector interrupts are on.
+ * For now only OR combinations are supported.
*/
#define SCA3000_MD_CTRL_PROT_MASK 0xC0
#define SCA3000_MD_CTRL_OR_Y 0x01
@@ -121,7 +126,8 @@
#define SCA3000_MD_CTRL_AND_X 0x10
#define SAC3000_MD_CTRL_AND_Z 0x20
-/* Some control registers of complex access methods requiring this register to
+/*
+ * Some control registers of complex access methods requiring this register to
* be used to remove a lock.
*/
#define SCA3000_REG_ADDR_UNLOCK 0x1e
@@ -139,7 +145,8 @@
/* Values of multiplexed registers (write to ctrl_data after select) */
#define SCA3000_REG_ADDR_CTRL_DATA 0x22
-/* Measurement modes available on some sca3000 series chips. Code assumes others
+/*
+ * Measurement modes available on some sca3000 series chips. Code assumes others
* may become available in the future.
*
* Bypass - Bypass the low-pass filter in the signal channel so as to increase
@@ -160,7 +167,6 @@
* struct sca3000_state - device instance state information
* @us: the associated spi device
* @info: chip variant information
- * @indio_dev: device information used by the IIO core
* @interrupt_handler_ws: event interrupt handler for all events
* @last_timestamp: the timestamp of the last event
* @mo_det_use_count: reference counter for the motion detection unit
diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c
index 32950ad9485..ed30e32e60d 100644
--- a/drivers/staging/iio/accel/sca3000_core.c
+++ b/drivers/staging/iio/accel/sca3000_core.c
@@ -32,7 +32,8 @@ enum sca3000_variant {
e05,
};
-/* Note where option modes are not defined, the chip simply does not
+/*
+ * Note where option modes are not defined, the chip simply does not
* support any.
* Other chips in the sca3000 series use i2c and are not included here.
*
@@ -191,7 +192,6 @@ error_ret:
return ret;
}
-/* Crucial that lock is called before calling this */
/**
* sca3000_read_ctrl_reg() read from lock protected control register.
*
@@ -250,9 +250,8 @@ error_ret:
}
#endif /* SCA3000_DEBUG */
-
/**
- * sca3000_show_reg() - sysfs interface to read the chip revision number
+ * sca3000_show_rev() - sysfs interface to read the chip revision number
**/
static ssize_t sca3000_show_rev(struct device *dev,
struct device_attribute *attr,
@@ -312,7 +311,7 @@ sca3000_show_available_measurement_modes(struct device *dev,
}
/**
- * sca3000_show_measurmenet_mode() sysfs read of current mode
+ * sca3000_show_measurement_mode() sysfs read of current mode
**/
static ssize_t
sca3000_show_measurement_mode(struct device *dev,
@@ -403,7 +402,8 @@ error_ret:
}
-/* Not even vaguely standard attributes so defined here rather than
+/*
+ * Not even vaguely standard attributes so defined here rather than
* in the relevant IIO core headers
*/
static IIO_DEVICE_ATTR(measurement_mode_available, S_IRUGO,
@@ -419,8 +419,11 @@ static IIO_DEVICE_ATTR(measurement_mode, S_IRUGO | S_IWUSR,
static IIO_DEVICE_ATTR(revision, S_IRUGO, sca3000_show_rev, NULL, 0);
-#define SCA3000_EVENT_MASK \
- (IIO_EV_BIT(IIO_EV_TYPE_MAG, IIO_EV_DIR_RISING))
+static const struct iio_event_spec sca3000_event = {
+ .type = IIO_EV_TYPE_MAG,
+ .dir = IIO_EV_DIR_RISING,
+ .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
+};
#define SCA3000_CHAN(index, mod) \
{ \
@@ -437,7 +440,8 @@ static IIO_DEVICE_ATTR(revision, S_IRUGO, sca3000_show_rev, NULL, 0);
.storagebits = 16, \
.shift = 5, \
}, \
- .event_mask = SCA3000_EVENT_MASK, \
+ .event_spec = &sca3000_event, \
+ .num_event_specs = 1, \
}
static const struct iio_chan_spec sca3000_channels[] = {
@@ -446,6 +450,18 @@ static const struct iio_chan_spec sca3000_channels[] = {
SCA3000_CHAN(2, IIO_MOD_Z),
};
+static const struct iio_chan_spec sca3000_channels_with_temp[] = {
+ SCA3000_CHAN(0, IIO_MOD_X),
+ SCA3000_CHAN(1, IIO_MOD_Y),
+ SCA3000_CHAN(2, IIO_MOD_Z),
+ {
+ .type = IIO_TEMP,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |
+ BIT(IIO_CHAN_INFO_OFFSET),
+ },
+};
+
static u8 sca3000_addresses[3][3] = {
[0] = {SCA3000_REG_ADDR_X_MSB, SCA3000_REG_CTRL_SEL_MD_X_TH,
SCA3000_MD_CTRL_OR_X},
@@ -468,19 +484,30 @@ static int sca3000_read_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_RAW:
mutex_lock(&st->lock);
- if (st->mo_det_use_count) {
- mutex_unlock(&st->lock);
- return -EBUSY;
- }
- address = sca3000_addresses[chan->address][0];
- ret = sca3000_read_data_short(st, address, 2);
- if (ret < 0) {
- mutex_unlock(&st->lock);
- return ret;
+ if (chan->type == IIO_ACCEL) {
+ if (st->mo_det_use_count) {
+ mutex_unlock(&st->lock);
+ return -EBUSY;
+ }
+ address = sca3000_addresses[chan->address][0];
+ ret = sca3000_read_data_short(st, address, 2);
+ if (ret < 0) {
+ mutex_unlock(&st->lock);
+ return ret;
+ }
+ *val = (be16_to_cpup((__be16 *)st->rx) >> 3) & 0x1FFF;
+ *val = ((*val) << (sizeof(*val)*8 - 13)) >>
+ (sizeof(*val)*8 - 13);
+ } else {
+ /* get the temperature when available */
+ ret = sca3000_read_data_short(st,
+ SCA3000_REG_ADDR_TEMP_MSB, 2);
+ if (ret < 0) {
+ mutex_unlock(&st->lock);
+ return ret;
+ }
+ *val = ((st->rx[0] & 0x3F) << 3) | ((st->rx[1] & 0xE0) >> 5);
}
- *val = (be16_to_cpup((__be16 *)st->rx) >> 3) & 0x1FFF;
- *val = ((*val) << (sizeof(*val)*8 - 13)) >>
- (sizeof(*val)*8 - 13);
mutex_unlock(&st->lock);
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
@@ -490,6 +517,10 @@ static int sca3000_read_raw(struct iio_dev *indio_dev,
else /* temperature */
*val2 = 555556;
return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_CHAN_INFO_OFFSET:
+ *val = -214;
+ *val2 = 600000;
+ return IIO_VAL_INT_PLUS_MICRO;
default:
return -EINVAL;
}
@@ -543,7 +574,7 @@ error_ret:
return ret;
}
/**
- * __sca3000_get_base_frequency() obtain mode specific base frequency
+ * __sca3000_get_base_freq() obtain mode specific base frequency
*
* lock must be held
**/
@@ -624,9 +655,9 @@ static ssize_t sca3000_set_frequency(struct device *dev,
struct sca3000_state *st = iio_priv(indio_dev);
int ret, base_freq = 0;
int ctrlval;
- long val;
+ int val;
- ret = strict_strtol(buf, 10, &val);
+ ret = kstrtoint(buf, 10, &val);
if (ret)
return ret;
@@ -659,7 +690,8 @@ error_free_lock:
return ret ? ret : len;
}
-/* Should only really be registered if ring buffer support is compiled in.
+/*
+ * Should only really be registered if ring buffer support is compiled in.
* Does no harm however and doing it right would add a fair bit of complexity
*/
static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(sca3000_read_av_freq);
@@ -668,47 +700,19 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
sca3000_read_frequency,
sca3000_set_frequency);
-
-/**
- * sca3000_read_temp() sysfs interface to get the temperature when available
- *
-* The alignment of data in here is downright odd. See data sheet.
-* Converting this into a meaningful value is left to inline functions in
-* userspace part of header.
-**/
-static ssize_t sca3000_read_temp(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct sca3000_state *st = iio_priv(indio_dev);
- int ret;
- int val;
- ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_TEMP_MSB, 2);
- if (ret < 0)
- goto error_ret;
- val = ((st->rx[0] & 0x3F) << 3) | ((st->rx[1] & 0xE0) >> 5);
-
- return sprintf(buf, "%d\n", val);
-
-error_ret:
- return ret;
-}
-static IIO_DEV_ATTR_TEMP_RAW(sca3000_read_temp);
-
-static IIO_CONST_ATTR_TEMP_SCALE("0.555556");
-static IIO_CONST_ATTR_TEMP_OFFSET("-214.6");
-
/**
* sca3000_read_thresh() - query of a threshold
**/
static int sca3000_read_thresh(struct iio_dev *indio_dev,
- u64 e,
- int *val)
+ 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)
{
int ret, i;
struct sca3000_state *st = iio_priv(indio_dev);
- int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e);
+ int num = chan->channel2;
mutex_lock(&st->lock);
ret = sca3000_read_ctrl_reg(st, sca3000_addresses[num][1]);
mutex_unlock(&st->lock);
@@ -724,18 +728,21 @@ static int sca3000_read_thresh(struct iio_dev *indio_dev,
ARRAY_SIZE(st->info->mot_det_mult_xz))
*val += st->info->mot_det_mult_xz[i];
- return 0;
+ return IIO_VAL_INT;
}
/**
* sca3000_write_thresh() control of threshold
**/
static int sca3000_write_thresh(struct iio_dev *indio_dev,
- u64 e,
- int val)
+ 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 sca3000_state *st = iio_priv(indio_dev);
- int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e);
+ int num = chan->channel2;
int ret;
int i;
u8 nonlinear = 0;
@@ -772,33 +779,16 @@ static struct attribute *sca3000_attributes[] = {
NULL,
};
-static struct attribute *sca3000_attributes_with_temp[] = {
- &iio_dev_attr_revision.dev_attr.attr,
- &iio_dev_attr_measurement_mode_available.dev_attr.attr,
- &iio_dev_attr_measurement_mode.dev_attr.attr,
- &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
- &iio_dev_attr_sampling_frequency.dev_attr.attr,
- /* Only present if temp sensor is */
- &iio_dev_attr_in_temp_raw.dev_attr.attr,
- &iio_const_attr_in_temp_offset.dev_attr.attr,
- &iio_const_attr_in_temp_scale.dev_attr.attr,
- NULL,
-};
-
static const struct attribute_group sca3000_attribute_group = {
.attrs = sca3000_attributes,
};
-static const struct attribute_group sca3000_attribute_group_with_temp = {
- .attrs = sca3000_attributes_with_temp,
-};
-
-/* RING RELATED interrupt handler */
-/* depending on event, push to the ring buffer event chrdev or the event one */
-
/**
* sca3000_event_handler() - handling ring and non ring events
*
+ * Ring related interrupt handler. Depending on event, push to
+ * the ring buffer event chrdev or the event one.
+ *
* This function is complicated by the fact that the devices can signify ring
* and non ring events via the same interrupt line and they can only
* be distinguished via a read of the relevant status register.
@@ -810,7 +800,8 @@ static irqreturn_t sca3000_event_handler(int irq, void *private)
int ret, val;
s64 last_timestamp = iio_get_time_ns();
- /* Could lead if badly timed to an extra read of status reg,
+ /*
+ * Could lead if badly timed to an extra read of status reg,
* but ensures no interrupt is missed.
*/
mutex_lock(&st->lock);
@@ -866,12 +857,14 @@ done:
* sca3000_read_event_config() what events are enabled
**/
static int sca3000_read_event_config(struct iio_dev *indio_dev,
- u64 e)
+ const struct iio_chan_spec *chan,
+ enum iio_event_type type,
+ enum iio_event_direction dir)
{
struct sca3000_state *st = iio_priv(indio_dev);
int ret;
u8 protect_mask = 0x03;
- int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e);
+ int num = chan->channel2;
/* read current value of mode register */
mutex_lock(&st->lock);
@@ -923,7 +916,6 @@ static ssize_t sca3000_query_free_fall_mode(struct device *dev,
* the device falls more than 25cm. This has not been tested due
* to fragile wiring.
**/
-
static ssize_t sca3000_set_free_fall_mode(struct device *dev,
struct device_attribute *attr,
const char *buf,
@@ -931,12 +923,12 @@ static ssize_t sca3000_set_free_fall_mode(struct device *dev,
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct sca3000_state *st = iio_priv(indio_dev);
- long val;
+ u8 val;
int ret;
u8 protect_mask = SCA3000_FREE_FALL_DETECT;
mutex_lock(&st->lock);
- ret = strict_strtol(buf, 10, &val);
+ ret = kstrtou8(buf, 10, &val);
if (ret)
goto error_ret;
@@ -945,7 +937,7 @@ static ssize_t sca3000_set_free_fall_mode(struct device *dev,
if (ret)
goto error_ret;
- /*if off and should be on*/
+ /* if off and should be on */
if (val && !(st->rx[0] & protect_mask))
ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
(st->rx[0] | SCA3000_FREE_FALL_DETECT));
@@ -960,7 +952,7 @@ error_ret:
}
/**
- * sca3000_set_mo_det() simple on off control for motion detector
+ * sca3000_write_event_config() simple on off control for motion detector
*
* This is a per axis control, but enabling any will result in the
* motion detector unit being enabled.
@@ -969,22 +961,26 @@ error_ret:
* this mode is disabled. Currently normal mode is assumed.
**/
static int sca3000_write_event_config(struct iio_dev *indio_dev,
- u64 e,
+ const struct iio_chan_spec *chan,
+ enum iio_event_type type,
+ enum iio_event_direction dir,
int state)
{
struct sca3000_state *st = iio_priv(indio_dev);
int ret, ctrlval;
u8 protect_mask = 0x03;
- int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e);
+ int num = chan->channel2;
mutex_lock(&st->lock);
- /* First read the motion detector config to find out if
- * this axis is on*/
+ /*
+ * First read the motion detector config to find out if
+ * this axis is on
+ */
ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_MD_CTRL);
if (ret < 0)
goto exit_point;
ctrlval = ret;
- /* Off and should be on */
+ /* if off and should be on */
if (state && !(ctrlval & sca3000_addresses[num][2])) {
ret = sca3000_write_ctrl_reg(st,
SCA3000_REG_CTRL_SEL_MD_CTRL,
@@ -1007,7 +1003,7 @@ static int sca3000_write_event_config(struct iio_dev *indio_dev,
ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
if (ret)
goto exit_point;
- /*if off and should be on*/
+ /* if off and should be on */
if ((st->mo_det_use_count)
&& ((st->rx[0] & protect_mask) != SCA3000_MEAS_MODE_MOT_DET))
ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
@@ -1053,7 +1049,7 @@ static struct attribute_group sca3000_event_attribute_group = {
* Devices use flash memory to store many of the register values
* and hence can come up in somewhat unpredictable states.
* Hence reset everything on driver load.
- **/
+ **/
static int sca3000_clean_setup(struct sca3000_state *st)
{
int ret;
@@ -1093,9 +1089,11 @@ static int sca3000_clean_setup(struct sca3000_state *st)
| SCA3000_INT_MASK_ACTIVE_LOW);
if (ret)
goto error_ret;
- /* Select normal measurement mode, free fall off, ring off */
- /* Ring in 12 bit mode - it is fine to overwrite reserved bits 3,5
- * as that occurs in one of the example on the datasheet */
+ /*
+ * Select normal measurement mode, free fall off, ring off
+ * Ring in 12 bit mode - it is fine to overwrite reserved bits 3,5
+ * as that occurs in one of the example on the datasheet
+ */
ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
if (ret)
goto error_ret;
@@ -1119,27 +1117,15 @@ static const struct iio_info sca3000_info = {
.driver_module = THIS_MODULE,
};
-static const struct iio_info sca3000_info_with_temp = {
- .attrs = &sca3000_attribute_group_with_temp,
- .read_raw = &sca3000_read_raw,
- .read_event_value = &sca3000_read_thresh,
- .write_event_value = &sca3000_write_thresh,
- .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)
{
int ret;
struct sca3000_state *st;
struct iio_dev *indio_dev;
- indio_dev = iio_device_alloc(sizeof(*st));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (!indio_dev)
+ return -ENOMEM;
st = iio_priv(indio_dev);
spi_set_drvdata(spi, indio_dev);
@@ -1150,10 +1136,12 @@ static int sca3000_probe(struct spi_device *spi)
indio_dev->dev.parent = &spi->dev;
indio_dev->name = spi_get_device_id(spi)->name;
- if (st->info->temp_output)
- indio_dev->info = &sca3000_info_with_temp;
- else {
- indio_dev->info = &sca3000_info;
+ indio_dev->info = &sca3000_info;
+ if (st->info->temp_output) {
+ indio_dev->channels = sca3000_channels_with_temp;
+ indio_dev->num_channels =
+ ARRAY_SIZE(sca3000_channels_with_temp);
+ } else {
indio_dev->channels = sca3000_channels;
indio_dev->num_channels = ARRAY_SIZE(sca3000_channels);
}
@@ -1162,7 +1150,7 @@ static int sca3000_probe(struct spi_device *spi)
sca3000_configure_ring(indio_dev);
ret = iio_device_register(indio_dev);
if (ret < 0)
- goto error_free_dev;
+ return ret;
ret = iio_buffer_register(indio_dev,
sca3000_channels,
@@ -1198,10 +1186,6 @@ error_unregister_ring:
iio_buffer_unregister(indio_dev);
error_unregister_dev:
iio_device_unregister(indio_dev);
-error_free_dev:
- iio_device_free(indio_dev);
-
-error_ret:
return ret;
}
@@ -1228,14 +1212,13 @@ static int sca3000_remove(struct spi_device *spi)
struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct sca3000_state *st = iio_priv(indio_dev);
- /* Must ensure no interrupts can be generated after this!*/
+ /* Must ensure no interrupts can be generated after this! */
sca3000_stop_all_interrupts(st);
if (spi->irq)
free_irq(spi->irq, indio_dev);
iio_device_unregister(indio_dev);
iio_buffer_unregister(indio_dev);
sca3000_unconfigure_ring(indio_dev);
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c
index 3e5e860aa38..198710651e0 100644
--- a/drivers/staging/iio/accel/sca3000_ring.c
+++ b/drivers/staging/iio/accel/sca3000_ring.c
@@ -177,11 +177,11 @@ static ssize_t sca3000_set_ring_int(struct device *dev,
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct sca3000_state *st = iio_priv(indio_dev);
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
- long val;
+ u8 val;
int ret;
mutex_lock(&st->lock);
- ret = strict_strtol(buf, 10, &val);
+ ret = kstrtou8(buf, 10, &val);
if (ret)
goto error_ret;
ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_MASK, 1);
@@ -252,7 +252,7 @@ static struct iio_buffer *sca3000_rb_allocate(struct iio_dev *indio_dev)
struct iio_buffer *buf;
struct iio_hw_buffer *ring;
- ring = kzalloc(sizeof *ring, GFP_KERNEL);
+ ring = kzalloc(sizeof(*ring), GFP_KERNEL);
if (!ring)
return NULL;
@@ -265,7 +265,7 @@ static struct iio_buffer *sca3000_rb_allocate(struct iio_dev *indio_dev)
return buf;
}
-static inline void sca3000_rb_free(struct iio_buffer *r)
+static void sca3000_ring_release(struct iio_buffer *r)
{
kfree(iio_to_hw_buf(r));
}
@@ -274,23 +274,28 @@ static const struct iio_buffer_access_funcs sca3000_ring_access_funcs = {
.read_first_n = &sca3000_read_first_n_hw_rb,
.get_length = &sca3000_ring_get_length,
.get_bytes_per_datum = &sca3000_ring_get_bytes_per_datum,
+ .release = sca3000_ring_release,
};
int sca3000_configure_ring(struct iio_dev *indio_dev)
{
- indio_dev->buffer = sca3000_rb_allocate(indio_dev);
- if (indio_dev->buffer == NULL)
+ struct iio_buffer *buffer;
+
+ buffer = sca3000_rb_allocate(indio_dev);
+ if (buffer == NULL)
return -ENOMEM;
indio_dev->modes |= INDIO_BUFFER_HARDWARE;
indio_dev->buffer->access = &sca3000_ring_access_funcs;
+ iio_device_attach_buffer(indio_dev, buffer);
+
return 0;
}
void sca3000_unconfigure_ring(struct iio_dev *indio_dev)
{
- sca3000_rb_free(indio_dev->buffer);
+ iio_buffer_put(indio_dev->buffer);
}
static inline
@@ -304,7 +309,7 @@ int __sca3000_hw_ring_state_set(struct iio_dev *indio_dev, bool state)
if (ret)
goto error_ret;
if (state) {
- printk(KERN_INFO "supposedly enabling ring buffer\n");
+ dev_info(&indio_dev->dev, "supposedly enabling ring buffer\n");
ret = sca3000_write_reg(st,
SCA3000_REG_ADDR_MODE,
(st->rx[0] | SCA3000_RING_BUF_ENABLE));
diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig
index cabc7a367db..b87e382ad76 100644
--- a/drivers/staging/iio/adc/Kconfig
+++ b/drivers/staging/iio/adc/Kconfig
@@ -37,26 +37,6 @@ config AD7606_IFACE_SPI
Say yes here to include parallel interface support on the AD7606
ADC driver.
-config AD799X
- tristate "Analog Devices AD799x ADC driver"
- depends on I2C
- select IIO_TRIGGER if IIO_BUFFER
- select AD799X_RING_BUFFER
- help
- Say yes here to build support for Analog Devices:
- ad7991, ad7995, ad7999, ad7992, ad7993, ad7994, ad7997, ad7998
- i2c analog to digital converters (ADC). Provides direct access
- via sysfs.
-
-config AD799X_RING_BUFFER
- bool "Analog Devices AD799x: use ring buffer"
- depends on AD799X
- select IIO_BUFFER
- select IIO_TRIGGERED_BUFFER
- help
- Say yes here to include ring buffer support in the AD799X
- ADC driver.
-
config AD7780
tristate "Analog Devices AD7780 and similar ADCs driver"
depends on SPI
@@ -102,7 +82,8 @@ config AD7280
config LPC32XX_ADC
tristate "NXP LPC32XX ADC"
- depends on ARCH_LPC32XX
+ depends on ARCH_LPC32XX || COMPILE_TEST
+ depends on HAS_IOMEM
help
Say yes here to build support for the integrated ADC inside the
LPC32XX SoC. Note that this feature uses the same hardware as the
@@ -113,7 +94,9 @@ config LPC32XX_ADC
config MXS_LRADC
tristate "Freescale i.MX23/i.MX28 LRADC"
- depends on ARCH_MXS
+ depends on ARCH_MXS || COMPILE_TEST
+ depends on INPUT
+ select STMP_DEVICE
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
@@ -125,7 +108,8 @@ config MXS_LRADC
config SPEAR_ADC
tristate "ST SPEAr ADC"
- depends on PLAT_SPEAR
+ depends on PLAT_SPEAR || COMPILE_TEST
+ depends on HAS_IOMEM
help
Say yes here to build support for the integrated ADC inside the
ST SPEAr SoC. Provides direct access via sysfs.
diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile
index 3e9fb143d25..afdcd1ff08f 100644
--- a/drivers/staging/iio/adc/Makefile
+++ b/drivers/staging/iio/adc/Makefile
@@ -8,10 +8,6 @@ ad7606-$(CONFIG_AD7606_IFACE_PARALLEL) += ad7606_par.o
ad7606-$(CONFIG_AD7606_IFACE_SPI) += ad7606_spi.o
obj-$(CONFIG_AD7606) += ad7606.o
-ad799x-y := ad799x_core.o
-ad799x-$(CONFIG_AD799X_RING_BUFFER) += ad799x_ring.o
-obj-$(CONFIG_AD799X) += ad799x.o
-
obj-$(CONFIG_AD7291) += ad7291.o
obj-$(CONFIG_AD7780) += ad7780.o
obj-$(CONFIG_AD7816) += ad7816.o
diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c
index 3283e282953..83bb44b3815 100644
--- a/drivers/staging/iio/adc/ad7192.c
+++ b/drivers/staging/iio/adc/ad7192.c
@@ -623,17 +623,17 @@ static int ad7192_probe(struct spi_device *spi)
return -ENODEV;
}
- indio_dev = iio_device_alloc(sizeof(*st));
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
st = iio_priv(indio_dev);
- st->reg = regulator_get(&spi->dev, "vcc");
+ st->reg = devm_regulator_get(&spi->dev, "vcc");
if (!IS_ERR(st->reg)) {
ret = regulator_enable(st->reg);
if (ret)
- goto error_put_reg;
+ return ret;
voltage_uv = regulator_get_voltage(st->reg);
}
@@ -677,11 +677,6 @@ error_remove_trigger:
error_disable_reg:
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
-error_put_reg:
- if (!IS_ERR(st->reg))
- regulator_put(st->reg);
-
- iio_device_free(indio_dev);
return ret;
}
@@ -694,10 +689,8 @@ static int ad7192_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
ad_sd_cleanup_buffer_and_trigger(indio_dev);
- if (!IS_ERR(st->reg)) {
+ if (!IS_ERR(st->reg))
regulator_disable(st->reg);
- regulator_put(st->reg);
- }
return 0;
}
diff --git a/drivers/staging/iio/adc/ad7280a.c b/drivers/staging/iio/adc/ad7280a.c
index c19618bc37c..d215edf66af 100644
--- a/drivers/staging/iio/adc/ad7280a.c
+++ b/drivers/staging/iio/adc/ad7280a.c
@@ -134,6 +134,8 @@ struct ad7280_state {
unsigned char aux_threshhigh;
unsigned char aux_threshlow;
unsigned char cb_mask[AD7280A_MAX_CHAIN];
+
+ __be32 buf[2] ____cacheline_aligned;
};
static void ad7280_crc8_build_table(unsigned char *crc_tab)
@@ -189,22 +191,22 @@ static void ad7280_delay(struct ad7280_state *st)
msleep(1);
}
-static int __ad7280_read32(struct spi_device *spi, unsigned *val)
+static int __ad7280_read32(struct ad7280_state *st, unsigned *val)
{
- unsigned rx_buf, tx_buf = cpu_to_be32(AD7280A_READ_TXVAL);
int ret;
-
struct spi_transfer t = {
- .tx_buf = &tx_buf,
- .rx_buf = &rx_buf,
+ .tx_buf = &st->buf[0],
+ .rx_buf = &st->buf[1],
.len = 4,
};
- ret = spi_sync_transfer(spi, &t, 1);
+ st->buf[0] = cpu_to_be32(AD7280A_READ_TXVAL);
+
+ ret = spi_sync_transfer(st->spi, &t, 1);
if (ret)
return ret;
- *val = be32_to_cpu(rx_buf);
+ *val = be32_to_cpu(st->buf[1]);
return 0;
}
@@ -216,9 +218,9 @@ static int ad7280_write(struct ad7280_state *st, unsigned devaddr,
(val & 0xFF) << 13 | all << 12);
reg |= ad7280_calc_crc8(st->crc_tab, reg >> 11) << 3 | 0x2;
- reg = cpu_to_be32(reg);
+ st->buf[0] = cpu_to_be32(reg);
- return spi_write(st->spi, &reg, 4);
+ return spi_write(st->spi, &st->buf[0], 4);
}
static int ad7280_read(struct ad7280_state *st, unsigned devaddr,
@@ -248,7 +250,7 @@ static int ad7280_read(struct ad7280_state *st, unsigned devaddr,
if (ret)
return ret;
- __ad7280_read32(st->spi, &tmp);
+ __ad7280_read32(st, &tmp);
if (ad7280_check_crc(st, tmp))
return -EIO;
@@ -286,7 +288,7 @@ static int ad7280_read_channel(struct ad7280_state *st, unsigned devaddr,
ad7280_delay(st);
- __ad7280_read32(st->spi, &tmp);
+ __ad7280_read32(st, &tmp);
if (ad7280_check_crc(st, tmp))
return -EIO;
@@ -319,7 +321,7 @@ static int ad7280_read_all_channels(struct ad7280_state *st, unsigned cnt,
ad7280_delay(st);
for (i = 0; i < cnt; i++) {
- __ad7280_read32(st->spi, &tmp);
+ __ad7280_read32(st, &tmp);
if (ad7280_check_crc(st, tmp))
return -EIO;
@@ -362,7 +364,7 @@ static int ad7280_chain_setup(struct ad7280_state *st)
return ret;
for (n = 0; n <= AD7280A_MAX_CHAIN; n++) {
- __ad7280_read32(st->spi, &val);
+ __ad7280_read32(st, &val);
if (val == 0)
return n - 1;
@@ -441,7 +443,7 @@ static ssize_t ad7280_show_balance_timer(struct device *dev,
msecs = (ret >> 3) * 71500;
- return sprintf(buf, "%d\n", msecs);
+ return sprintf(buf, "%u\n", msecs);
}
static ssize_t ad7280_store_balance_timer(struct device *dev,
@@ -617,7 +619,7 @@ static ssize_t ad7280_read_channel_config(struct device *dev,
return -EINVAL;
}
- return sprintf(buf, "%d\n", val);
+ return sprintf(buf, "%u\n", val);
}
static ssize_t ad7280_write_channel_config(struct device *dev,
@@ -783,7 +785,6 @@ static int ad7280_read_raw(struct iio_dev *indio_dev,
long m)
{
struct ad7280_state *st = iio_priv(indio_dev);
- unsigned int scale_uv;
int ret;
switch (m) {
@@ -804,13 +805,12 @@ static int ad7280_read_raw(struct iio_dev *indio_dev,
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
if ((chan->address & 0xFF) <= AD7280A_CELL_VOLTAGE_6)
- scale_uv = (4000 * 1000) >> AD7280A_BITS;
+ *val = 4000;
else
- scale_uv = (5000 * 1000) >> AD7280A_BITS;
+ *val = 5000;
- *val = scale_uv / 1000;
- *val2 = (scale_uv % 1000) * 1000;
- return IIO_VAL_INT_PLUS_MICRO;
+ *val2 = AD7280A_BITS;
+ return IIO_VAL_FRACTIONAL_LOG2;
}
return -EINVAL;
}
@@ -835,8 +835,9 @@ static int ad7280_probe(struct spi_device *spi)
int ret;
const unsigned short tACQ_ns[4] = {465, 1010, 1460, 1890};
const unsigned short nAVG[4] = {1, 2, 4, 8};
- struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
+ struct iio_dev *indio_dev;
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
@@ -860,7 +861,7 @@ static int ad7280_probe(struct spi_device *spi)
ret = ad7280_chain_setup(st);
if (ret < 0)
- goto error_free_device;
+ return ret;
st->slave_num = ret;
st->scan_cnt = (st->slave_num + 1) * AD7280A_NUM_CH;
@@ -891,7 +892,7 @@ static int ad7280_probe(struct spi_device *spi)
ret = ad7280_channel_init(st);
if (ret < 0)
- goto error_free_device;
+ return ret;
indio_dev->num_channels = ret;
indio_dev->channels = st->channels;
@@ -940,9 +941,6 @@ error_free_attr:
error_free_channels:
kfree(st->channels);
-error_free_device:
- iio_device_free(indio_dev);
-
return ret;
}
@@ -960,7 +958,6 @@ static int ad7280_remove(struct spi_device *spi)
kfree(st->channels);
kfree(st->iio_attr);
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/adc/ad7291.c b/drivers/staging/iio/adc/ad7291.c
index 3fc79e58275..7194bd13876 100644
--- a/drivers/staging/iio/adc/ad7291.c
+++ b/drivers/staging/iio/adc/ad7291.c
@@ -164,97 +164,14 @@ static irqreturn_t ad7291_event_handler(int irq, void *private)
return IRQ_HANDLED;
}
-static inline ssize_t ad7291_show_hyst(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct ad7291_chip_info *chip = iio_priv(indio_dev);
- struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
- u16 data;
- int ret;
-
- ret = ad7291_i2c_read(chip, this_attr->address, &data);
- if (ret < 0)
- return ret;
-
- return sprintf(buf, "%d\n", data & AD7291_VALUE_MASK);
-}
-
-static inline ssize_t ad7291_set_hyst(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct ad7291_chip_info *chip = iio_priv(indio_dev);
- struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
- u16 data;
- int ret;
-
- ret = kstrtou16(buf, 10, &data);
-
- if (ret < 0)
- return ret;
- if (data > AD7291_VALUE_MASK)
- return -EINVAL;
-
- ret = ad7291_i2c_write(chip, this_attr->address, data);
- if (ret < 0)
- return ret;
-
- return len;
-}
-
-static IIO_DEVICE_ATTR(in_temp0_thresh_both_hyst_raw,
- S_IRUGO | S_IWUSR,
- ad7291_show_hyst, ad7291_set_hyst,
- AD7291_HYST(8));
-static IIO_DEVICE_ATTR(in_voltage0_thresh_both_hyst_raw,
- S_IRUGO | S_IWUSR,
- ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(0));
-static IIO_DEVICE_ATTR(in_voltage1_thresh_both_hyst_raw,
- S_IRUGO | S_IWUSR,
- ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(1));
-static IIO_DEVICE_ATTR(in_voltage2_thresh_both_hyst_raw,
- S_IRUGO | S_IWUSR,
- ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(2));
-static IIO_DEVICE_ATTR(in_voltage3_thresh_both_hyst_raw,
- S_IRUGO | S_IWUSR,
- ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(3));
-static IIO_DEVICE_ATTR(in_voltage4_thresh_both_hyst_raw,
- S_IRUGO | S_IWUSR,
- ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(4));
-static IIO_DEVICE_ATTR(in_voltage5_thresh_both_hyst_raw,
- S_IRUGO | S_IWUSR,
- ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(5));
-static IIO_DEVICE_ATTR(in_voltage6_thresh_both_hyst_raw,
- S_IRUGO | S_IWUSR,
- ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(6));
-static IIO_DEVICE_ATTR(in_voltage7_thresh_both_hyst_raw,
- S_IRUGO | S_IWUSR,
- ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(7));
-
-static struct attribute *ad7291_event_attributes[] = {
- &iio_dev_attr_in_temp0_thresh_both_hyst_raw.dev_attr.attr,
- &iio_dev_attr_in_voltage0_thresh_both_hyst_raw.dev_attr.attr,
- &iio_dev_attr_in_voltage1_thresh_both_hyst_raw.dev_attr.attr,
- &iio_dev_attr_in_voltage2_thresh_both_hyst_raw.dev_attr.attr,
- &iio_dev_attr_in_voltage3_thresh_both_hyst_raw.dev_attr.attr,
- &iio_dev_attr_in_voltage4_thresh_both_hyst_raw.dev_attr.attr,
- &iio_dev_attr_in_voltage5_thresh_both_hyst_raw.dev_attr.attr,
- &iio_dev_attr_in_voltage6_thresh_both_hyst_raw.dev_attr.attr,
- &iio_dev_attr_in_voltage7_thresh_both_hyst_raw.dev_attr.attr,
- NULL,
-};
-
-static unsigned int ad7291_threshold_reg(u64 event_code)
+static unsigned int ad7291_threshold_reg(const struct iio_chan_spec *chan,
+ enum iio_event_direction dir, enum iio_event_info info)
{
unsigned int offset;
- switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
+ switch (chan->type) {
case IIO_VOLTAGE:
- offset = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
+ offset = chan->channel;
break;
case IIO_TEMP:
offset = 8;
@@ -263,69 +180,78 @@ static unsigned int ad7291_threshold_reg(u64 event_code)
return 0;
}
- if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING)
- return AD7291_DATA_LOW(offset);
- else
- return AD7291_DATA_HIGH(offset);
+ switch (info) {
+ case IIO_EV_INFO_VALUE:
+ if (dir == IIO_EV_DIR_FALLING)
+ return AD7291_DATA_HIGH(offset);
+ else
+ return AD7291_DATA_LOW(offset);
+ case IIO_EV_INFO_HYSTERESIS:
+ return AD7291_HYST(offset);
+ default:
+ break;
+ }
+ return 0;
}
static int ad7291_read_event_value(struct iio_dev *indio_dev,
- u64 event_code,
- int *val)
+ 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 ad7291_chip_info *chip = iio_priv(indio_dev);
int ret;
u16 uval;
- ret = ad7291_i2c_read(chip, ad7291_threshold_reg(event_code), &uval);
+ ret = ad7291_i2c_read(chip, ad7291_threshold_reg(chan, dir, info),
+ &uval);
if (ret < 0)
return ret;
- switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
- case IIO_VOLTAGE:
+ if (info == IIO_EV_INFO_HYSTERESIS || chan->type == IIO_VOLTAGE)
*val = uval & AD7291_VALUE_MASK;
- return 0;
- case IIO_TEMP:
+
+ else
*val = sign_extend32(uval, 11);
- return 0;
- default:
- return -EINVAL;
- };
+
+ return IIO_VAL_INT;
}
static int ad7291_write_event_value(struct iio_dev *indio_dev,
- u64 event_code,
- int val)
+ 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 ad7291_chip_info *chip = iio_priv(indio_dev);
- switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
- case IIO_VOLTAGE:
+ if (info == IIO_EV_INFO_HYSTERESIS || chan->type == IIO_VOLTAGE) {
if (val > AD7291_VALUE_MASK || val < 0)
return -EINVAL;
- break;
- case IIO_TEMP:
+ } else {
if (val > 2047 || val < -2048)
return -EINVAL;
- break;
- default:
- return -EINVAL;
}
- return ad7291_i2c_write(chip, ad7291_threshold_reg(event_code), val);
+ return ad7291_i2c_write(chip, ad7291_threshold_reg(chan, dir, info),
+ val);
}
static int ad7291_read_event_config(struct iio_dev *indio_dev,
- u64 event_code)
+ const struct iio_chan_spec *chan,
+ enum iio_event_type type,
+ enum iio_event_direction dir)
{
struct ad7291_chip_info *chip = iio_priv(indio_dev);
/* To be enabled the channel must simply be on. If any are enabled
we are in continuous sampling mode */
- switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
+ switch (chan->type) {
case IIO_VOLTAGE:
- if (chip->c_mask &
- (1 << (15 - IIO_EVENT_CODE_EXTRACT_CHAN(event_code))))
+ if (chip->c_mask & (1 << (15 - chan->channel)))
return 1;
else
return 0;
@@ -339,11 +265,14 @@ static int ad7291_read_event_config(struct iio_dev *indio_dev,
}
static int ad7291_write_event_config(struct iio_dev *indio_dev,
- u64 event_code,
+ const struct iio_chan_spec *chan,
+ enum iio_event_type type,
+ enum iio_event_direction dir,
int state)
{
int ret = 0;
struct ad7291_chip_info *chip = iio_priv(indio_dev);
+ unsigned int mask;
u16 regval;
mutex_lock(&chip->state_lock);
@@ -354,16 +283,14 @@ static int ad7291_write_event_config(struct iio_dev *indio_dev,
* Possible to disable temp as well but that makes single read tricky.
*/
- switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+ mask = BIT(15 - chan->channel);
+
+ switch (chan->type) {
case IIO_VOLTAGE:
- if ((!state) && (chip->c_mask & (1 << (15 -
- IIO_EVENT_CODE_EXTRACT_CHAN(event_code)))))
- chip->c_mask &= ~(1 << (15 - IIO_EVENT_CODE_EXTRACT_CHAN
- (event_code)));
- else if (state && (!(chip->c_mask & (1 << (15 -
- IIO_EVENT_CODE_EXTRACT_CHAN(event_code))))))
- chip->c_mask |= (1 << (15 - IIO_EVENT_CODE_EXTRACT_CHAN
- (event_code)));
+ if ((!state) && (chip->c_mask & mask))
+ chip->c_mask &= ~mask;
+ else if (state && (!(chip->c_mask & mask)))
+ chip->c_mask |= mask;
else
break;
@@ -473,6 +400,24 @@ static int ad7291_read_raw(struct iio_dev *indio_dev,
}
}
+static const struct iio_event_spec ad7291_events[] = {
+ {
+ .type = IIO_EV_TYPE_THRESH,
+ .dir = IIO_EV_DIR_RISING,
+ .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+ BIT(IIO_EV_INFO_ENABLE),
+ }, {
+ .type = IIO_EV_TYPE_THRESH,
+ .dir = IIO_EV_DIR_FALLING,
+ .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+ BIT(IIO_EV_INFO_ENABLE),
+ }, {
+ .type = IIO_EV_TYPE_THRESH,
+ .dir = IIO_EV_DIR_EITHER,
+ .mask_separate = BIT(IIO_EV_INFO_HYSTERESIS),
+ },
+};
+
#define AD7291_VOLTAGE_CHAN(_chan) \
{ \
.type = IIO_VOLTAGE, \
@@ -480,8 +425,8 @@ static int ad7291_read_raw(struct iio_dev *indio_dev,
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
.indexed = 1, \
.channel = _chan, \
- .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING)|\
- IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING) \
+ .event_spec = ad7291_events, \
+ .num_event_specs = ARRAY_SIZE(ad7291_events), \
}
static const struct iio_chan_spec ad7291_channels[] = {
@@ -500,23 +445,18 @@ static const struct iio_chan_spec ad7291_channels[] = {
BIT(IIO_CHAN_INFO_SCALE),
.indexed = 1,
.channel = 0,
- .event_mask =
- IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING)|
- IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)
+ .event_spec = ad7291_events,
+ .num_event_specs = ARRAY_SIZE(ad7291_events),
}
};
-static struct attribute_group ad7291_event_attribute_group = {
- .attrs = ad7291_event_attributes,
-};
-
static const struct iio_info ad7291_info = {
.read_raw = &ad7291_read_raw,
.read_event_config = &ad7291_read_event_config,
.write_event_config = &ad7291_write_event_config,
.read_event_value = &ad7291_read_event_value,
.write_event_value = &ad7291_write_event_value,
- .event_attrs = &ad7291_event_attribute_group,
+ .driver_module = THIS_MODULE,
};
static int ad7291_probe(struct i2c_client *client,
@@ -525,23 +465,21 @@ static int ad7291_probe(struct i2c_client *client,
struct ad7291_platform_data *pdata = client->dev.platform_data;
struct ad7291_chip_info *chip;
struct iio_dev *indio_dev;
- int ret = 0;
+ int ret;
- indio_dev = iio_device_alloc(sizeof(*chip));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
+ if (!indio_dev)
+ return -ENOMEM;
chip = iio_priv(indio_dev);
if (pdata && pdata->use_external_ref) {
- chip->reg = regulator_get(&client->dev, "vref");
+ chip->reg = devm_regulator_get(&client->dev, "vref");
if (IS_ERR(chip->reg))
- goto error_free;
+ return PTR_ERR(chip->reg);
ret = regulator_enable(chip->reg);
if (ret)
- goto error_put_reg;
+ return ret;
}
mutex_init(&chip->state_lock);
@@ -600,12 +538,7 @@ error_unreg_irq:
error_disable_reg:
if (chip->reg)
regulator_disable(chip->reg);
-error_put_reg:
- if (chip->reg)
- regulator_put(chip->reg);
-error_free:
- iio_device_free(indio_dev);
-error_ret:
+
return ret;
}
@@ -619,12 +552,8 @@ static int ad7291_remove(struct i2c_client *client)
if (client->irq)
free_irq(client->irq, indio_dev);
- if (chip->reg) {
+ if (chip->reg)
regulator_disable(chip->reg);
- regulator_put(chip->reg);
- }
-
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/adc/ad7606.h b/drivers/staging/iio/adc/ad7606.h
index 9221a74efd1..ec89d055cf5 100644
--- a/drivers/staging/iio/adc/ad7606.h
+++ b/drivers/staging/iio/adc/ad7606.h
@@ -14,7 +14,7 @@
*/
/**
- * struct ad7606_platform_data - platform/board specifc information
+ * struct ad7606_platform_data - platform/board specific information
* @default_os: default oversampling value {0, 2, 4, 8, 16, 32, 64}
* @default_range: default range +/-{5000, 10000} mVolt
* @gpio_convst: number of gpio connected to the CONVST pin
@@ -41,8 +41,8 @@ struct ad7606_platform_data {
};
/**
- * struct ad7606_chip_info - chip specifc information
- * @name: indentification string for chip
+ * struct ad7606_chip_info - chip specific information
+ * @name: identification string for chip
* @int_vref_mv: the internal reference voltage
* @channels: channel specification
* @num_channels: number of channels
diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c
index 72868ceda36..f0f05f195d2 100644
--- a/drivers/staging/iio/adc/ad7606_core.c
+++ b/drivers/staging/iio/adc/ad7606_core.c
@@ -85,7 +85,6 @@ static int ad7606_read_raw(struct iio_dev *indio_dev,
{
int ret;
struct ad7606_state *st = iio_priv(indio_dev);
- unsigned int scale_uv;
switch (m) {
case IIO_CHAN_INFO_RAW:
@@ -101,11 +100,9 @@ static int ad7606_read_raw(struct iio_dev *indio_dev,
*val = (short) ret;
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
- scale_uv = (st->range * 1000 * 2)
- >> st->chip_info->channels[0].scan_type.realbits;
- *val = scale_uv / 1000;
- *val2 = (scale_uv % 1000) * 1000;
- return IIO_VAL_INT_PLUS_MICRO;
+ *val = st->range * 2;
+ *val2 = st->chip_info->channels[0].scan_type.realbits;
+ return IIO_VAL_FRACTIONAL_LOG2;
}
return -EINVAL;
}
@@ -242,7 +239,12 @@ static const struct attribute_group ad7606_attribute_group_range = {
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),\
.scan_index = num, \
- .scan_type = IIO_ST('s', 16, 16, 0), \
+ .scan_type = { \
+ .sign = 's', \
+ .realbits = 16, \
+ .storagebits = 16, \
+ .endianness = IIO_CPU, \
+ }, \
}
static const struct iio_chan_spec ad7606_8_channels[] = {
@@ -425,8 +427,7 @@ static irqreturn_t ad7606_interrupt(int irq, void *dev_id)
struct ad7606_state *st = iio_priv(indio_dev);
if (iio_buffer_enabled(indio_dev)) {
- if (!work_pending(&st->poll_work))
- schedule_work(&st->poll_work);
+ schedule_work(&st->poll_work);
} else {
st->done = true;
wake_up_interruptible(&st->wq_data_avail);
@@ -466,12 +467,11 @@ struct iio_dev *ad7606_probe(struct device *dev, int irq,
struct ad7606_platform_data *pdata = dev->platform_data;
struct ad7606_state *st;
int ret;
- struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
+ struct iio_dev *indio_dev;
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
+ if (!indio_dev)
+ return ERR_PTR(-ENOMEM);
st = iio_priv(indio_dev);
@@ -489,11 +489,11 @@ struct iio_dev *ad7606_probe(struct device *dev, int irq,
st->oversampling = pdata->default_os;
}
- st->reg = regulator_get(dev, "vcc");
+ st->reg = devm_regulator_get(dev, "vcc");
if (!IS_ERR(st->reg)) {
ret = regulator_enable(st->reg);
if (ret)
- goto error_put_reg;
+ return ERR_PTR(ret);
}
st->pdata = pdata;
@@ -554,11 +554,6 @@ error_free_gpios:
error_disable_reg:
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
-error_put_reg:
- if (!IS_ERR(st->reg))
- regulator_put(st->reg);
- iio_device_free(indio_dev);
-error_ret:
return ERR_PTR(ret);
}
@@ -570,13 +565,10 @@ int ad7606_remove(struct iio_dev *indio_dev, int irq)
ad7606_ring_cleanup(indio_dev);
free_irq(irq, indio_dev);
- if (!IS_ERR(st->reg)) {
+ if (!IS_ERR(st->reg))
regulator_disable(st->reg);
- regulator_put(st->reg);
- }
ad7606_free_gpios(st);
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c
index 2b25cb07fe4..3bf174cb19b 100644
--- a/drivers/staging/iio/adc/ad7606_ring.c
+++ b/drivers/staging/iio/adc/ad7606_ring.c
@@ -46,7 +46,6 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s)
struct ad7606_state *st = container_of(work_s, struct ad7606_state,
poll_work);
struct iio_dev *indio_dev = iio_priv_to_dev(st);
- s64 time_ns;
__u8 *buf;
int ret;
@@ -78,12 +77,7 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s)
goto done;
}
- time_ns = iio_get_time_ns();
-
- if (indio_dev->scan_timestamp)
- *((s64 *)(buf + indio_dev->scan_bytes - sizeof(s64))) = time_ns;
-
- iio_push_to_buffers(indio_dev, buf);
+ iio_push_to_buffers_with_timestamp(indio_dev, buf, iio_get_time_ns());
done:
gpio_set_value(st->pdata->gpio_convst, 0);
iio_trigger_notify_done(indio_dev->trig);
diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c
index e1f88603d7e..273add3ed63 100644
--- a/drivers/staging/iio/adc/ad7780.c
+++ b/drivers/staging/iio/adc/ad7780.c
@@ -90,17 +90,14 @@ static int ad7780_read_raw(struct iio_dev *indio_dev,
long m)
{
struct ad7780_state *st = iio_priv(indio_dev);
- unsigned long scale_uv;
switch (m) {
case IIO_CHAN_INFO_RAW:
return ad_sigma_delta_single_conversion(indio_dev, chan, val);
case IIO_CHAN_INFO_SCALE:
- scale_uv = (st->int_vref_mv * 100000 * st->gain)
- >> (chan->scan_type.realbits - 1);
- *val = scale_uv / 100000;
- *val2 = (scale_uv % 100000) * 10;
- return IIO_VAL_INT_PLUS_MICRO;
+ *val = st->int_vref_mv * st->gain;
+ *val2 = chan->scan_type.realbits - 1;
+ return IIO_VAL_FRACTIONAL_LOG2;
case IIO_CHAN_INFO_OFFSET:
*val -= (1 << (chan->scan_type.realbits - 1));
return IIO_VAL_INT;
@@ -171,7 +168,7 @@ static int ad7780_probe(struct spi_device *spi)
struct iio_dev *indio_dev;
int ret, voltage_uv = 0;
- indio_dev = iio_device_alloc(sizeof(*st));
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
@@ -180,11 +177,11 @@ static int ad7780_probe(struct spi_device *spi)
ad_sd_init(&st->sd, indio_dev, spi, &ad7780_sigma_delta_info);
- st->reg = regulator_get(&spi->dev, "vcc");
+ st->reg = devm_regulator_get(&spi->dev, "vcc");
if (!IS_ERR(st->reg)) {
ret = regulator_enable(st->reg);
if (ret)
- goto error_put_reg;
+ return ret;
voltage_uv = regulator_get_voltage(st->reg);
}
@@ -210,8 +207,8 @@ static int ad7780_probe(struct spi_device *spi)
if (pdata && gpio_is_valid(pdata->gpio_pdrst)) {
- ret = gpio_request_one(pdata->gpio_pdrst, GPIOF_OUT_INIT_LOW,
- "AD7780 /PDRST");
+ ret = devm_gpio_request_one(&spi->dev, pdata->gpio_pdrst,
+ GPIOF_OUT_INIT_LOW, "AD7780 /PDRST");
if (ret) {
dev_err(&spi->dev, "failed to request GPIO PDRST\n");
goto error_disable_reg;
@@ -223,7 +220,7 @@ static int ad7780_probe(struct spi_device *spi)
ret = ad_sd_setup_buffer_and_trigger(indio_dev);
if (ret)
- goto error_free_gpio;
+ goto error_disable_reg;
ret = iio_device_register(indio_dev);
if (ret)
@@ -233,17 +230,9 @@ static int ad7780_probe(struct spi_device *spi)
error_cleanup_buffer_and_trigger:
ad_sd_cleanup_buffer_and_trigger(indio_dev);
-error_free_gpio:
- if (pdata && gpio_is_valid(pdata->gpio_pdrst))
- gpio_free(pdata->gpio_pdrst);
error_disable_reg:
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
-error_put_reg:
- if (!IS_ERR(st->reg))
- regulator_put(st->reg);
-
- iio_device_free(indio_dev);
return ret;
}
@@ -256,14 +245,8 @@ static int ad7780_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
ad_sd_cleanup_buffer_and_trigger(indio_dev);
- if (gpio_is_valid(st->powerdown_gpio))
- gpio_free(st->powerdown_gpio);
-
- if (!IS_ERR(st->reg)) {
+ if (!IS_ERR(st->reg))
regulator_disable(st->reg);
- regulator_put(st->reg);
- }
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c
index 8470036a337..158d770f961 100644
--- a/drivers/staging/iio/adc/ad7816.c
+++ b/drivers/staging/iio/adc/ad7816.c
@@ -40,7 +40,7 @@
/*
- * struct ad7816_chip_info - chip specifc information
+ * struct ad7816_chip_info - chip specific information
*/
struct ad7816_chip_info {
@@ -356,11 +356,9 @@ static int ad7816_probe(struct spi_device *spi_dev)
return -EINVAL;
}
- indio_dev = iio_device_alloc(sizeof(*chip));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ indio_dev = devm_iio_device_alloc(&spi_dev->dev, sizeof(*chip));
+ if (!indio_dev)
+ return -ENOMEM;
chip = iio_priv(indio_dev);
/* this is only used for device removal purposes */
dev_set_drvdata(&spi_dev->dev, indio_dev);
@@ -372,25 +370,28 @@ static int ad7816_probe(struct spi_device *spi_dev)
chip->convert_pin = pins[1];
chip->busy_pin = pins[2];
- ret = gpio_request(chip->rdwr_pin, spi_get_device_id(spi_dev)->name);
+ ret = devm_gpio_request(&spi_dev->dev, chip->rdwr_pin,
+ spi_get_device_id(spi_dev)->name);
if (ret) {
dev_err(&spi_dev->dev, "Fail to request rdwr gpio PIN %d.\n",
chip->rdwr_pin);
- goto error_free_device;
+ return ret;
}
gpio_direction_input(chip->rdwr_pin);
- ret = gpio_request(chip->convert_pin, spi_get_device_id(spi_dev)->name);
+ ret = devm_gpio_request(&spi_dev->dev, chip->convert_pin,
+ spi_get_device_id(spi_dev)->name);
if (ret) {
dev_err(&spi_dev->dev, "Fail to request convert gpio PIN %d.\n",
chip->convert_pin);
- goto error_free_gpio_rdwr;
+ return ret;
}
gpio_direction_input(chip->convert_pin);
- ret = gpio_request(chip->busy_pin, spi_get_device_id(spi_dev)->name);
+ ret = devm_gpio_request(&spi_dev->dev, chip->busy_pin,
+ spi_get_device_id(spi_dev)->name);
if (ret) {
dev_err(&spi_dev->dev, "Fail to request busy gpio PIN %d.\n",
chip->busy_pin);
- goto error_free_gpio_convert;
+ return ret;
}
gpio_direction_input(chip->busy_pin);
@@ -401,53 +402,24 @@ static int ad7816_probe(struct spi_device *spi_dev)
if (spi_dev->irq) {
/* Only low trigger is supported in ad7816/7/8 */
- ret = request_threaded_irq(spi_dev->irq,
- NULL,
- &ad7816_event_handler,
- IRQF_TRIGGER_LOW | IRQF_ONESHOT,
- indio_dev->name,
- indio_dev);
+ ret = devm_request_threaded_irq(&spi_dev->dev, spi_dev->irq,
+ NULL,
+ &ad7816_event_handler,
+ IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ indio_dev->name,
+ indio_dev);
if (ret)
- goto error_free_gpio;
+ return ret;
}
- ret = iio_device_register(indio_dev);
+ ret = devm_iio_device_register(&spi_dev->dev, indio_dev);
if (ret)
- goto error_free_irq;
+ return ret;
dev_info(&spi_dev->dev, "%s temperature sensor and ADC registered.\n",
indio_dev->name);
return 0;
-error_free_irq:
- free_irq(spi_dev->irq, indio_dev);
-error_free_gpio:
- gpio_free(chip->busy_pin);
-error_free_gpio_convert:
- gpio_free(chip->convert_pin);
-error_free_gpio_rdwr:
- gpio_free(chip->rdwr_pin);
-error_free_device:
- iio_device_free(indio_dev);
-error_ret:
- return ret;
-}
-
-static int ad7816_remove(struct spi_device *spi_dev)
-{
- struct iio_dev *indio_dev = dev_get_drvdata(&spi_dev->dev);
- struct ad7816_chip_info *chip = iio_priv(indio_dev);
-
- iio_device_unregister(indio_dev);
- dev_set_drvdata(&spi_dev->dev, NULL);
- if (spi_dev->irq)
- free_irq(spi_dev->irq, indio_dev);
- gpio_free(chip->busy_pin);
- gpio_free(chip->convert_pin);
- gpio_free(chip->rdwr_pin);
- iio_device_free(indio_dev);
-
- return 0;
}
static const struct spi_device_id ad7816_id[] = {
@@ -465,7 +437,6 @@ static struct spi_driver ad7816_driver = {
.owner = THIS_MODULE,
},
.probe = ad7816_probe,
- .remove = ad7816_remove,
.id_table = ad7816_id,
};
module_spi_driver(ad7816_driver);
diff --git a/drivers/staging/iio/adc/ad799x.h b/drivers/staging/iio/adc/ad799x.h
deleted file mode 100644
index b51680c1c33..00000000000
--- a/drivers/staging/iio/adc/ad799x.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2010-2011 Michael Hennerich, Analog Devices Inc.
- * Copyright (C) 2008-2010 Jonathan Cameron
- *
- * 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.
- *
- * ad799x.h
- */
-
-#ifndef _AD799X_H_
-#define _AD799X_H_
-
-#define AD799X_CHANNEL_SHIFT 4
-#define AD799X_STORAGEBITS 16
-/*
- * AD7991, AD7995 and AD7999 defines
- */
-
-#define AD7991_REF_SEL 0x08
-#define AD7991_FLTR 0x04
-#define AD7991_BIT_TRIAL_DELAY 0x02
-#define AD7991_SAMPLE_DELAY 0x01
-
-/*
- * AD7992, AD7993, AD7994, AD7997 and AD7998 defines
- */
-
-#define AD7998_FLTR 0x08
-#define AD7998_ALERT_EN 0x04
-#define AD7998_BUSY_ALERT 0x02
-#define AD7998_BUSY_ALERT_POL 0x01
-
-#define AD7998_CONV_RES_REG 0x0
-#define AD7998_ALERT_STAT_REG 0x1
-#define AD7998_CONF_REG 0x2
-#define AD7998_CYCLE_TMR_REG 0x3
-#define AD7998_DATALOW_CH1_REG 0x4
-#define AD7998_DATAHIGH_CH1_REG 0x5
-#define AD7998_HYST_CH1_REG 0x6
-#define AD7998_DATALOW_CH2_REG 0x7
-#define AD7998_DATAHIGH_CH2_REG 0x8
-#define AD7998_HYST_CH2_REG 0x9
-#define AD7998_DATALOW_CH3_REG 0xA
-#define AD7998_DATAHIGH_CH3_REG 0xB
-#define AD7998_HYST_CH3_REG 0xC
-#define AD7998_DATALOW_CH4_REG 0xD
-#define AD7998_DATAHIGH_CH4_REG 0xE
-#define AD7998_HYST_CH4_REG 0xF
-
-#define AD7998_CYC_MASK 0x7
-#define AD7998_CYC_DIS 0x0
-#define AD7998_CYC_TCONF_32 0x1
-#define AD7998_CYC_TCONF_64 0x2
-#define AD7998_CYC_TCONF_128 0x3
-#define AD7998_CYC_TCONF_256 0x4
-#define AD7998_CYC_TCONF_512 0x5
-#define AD7998_CYC_TCONF_1024 0x6
-#define AD7998_CYC_TCONF_2048 0x7
-
-#define AD7998_ALERT_STAT_CLEAR 0xFF
-
-/*
- * AD7997 and AD7997 defines
- */
-
-#define AD7997_8_READ_SINGLE 0x80
-#define AD7997_8_READ_SEQUENCE 0x70
-/* TODO: move this into a common header */
-#define RES_MASK(bits) ((1 << (bits)) - 1)
-
-enum {
- ad7991,
- ad7995,
- ad7999,
- ad7992,
- ad7993,
- ad7994,
- ad7997,
- ad7998
-};
-
-struct ad799x_state;
-
-/**
- * struct ad799x_chip_info - chip specifc information
- * @channel: channel specification
- * @num_channels: number of channels
- * @monitor_mode: whether the chip supports monitor interrupts
- * @default_config: device default configuration
- * @event_attrs: pointer to the monitor event attribute group
- */
-
-struct ad799x_chip_info {
- struct iio_chan_spec channel[9];
- int num_channels;
- u16 default_config;
- const struct iio_info *info;
-};
-
-struct ad799x_state {
- struct i2c_client *client;
- const struct ad799x_chip_info *chip_info;
- struct regulator *reg;
- u16 int_vref_mv;
- unsigned id;
- u16 config;
-
- u8 *rx_buf;
- unsigned int transfer_size;
-};
-
-/*
- * TODO: struct ad799x_platform_data needs to go into include/linux/iio
- */
-
-struct ad799x_platform_data {
- u16 vref_mv;
-};
-
-#ifdef CONFIG_AD799X_RING_BUFFER
-int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev);
-void ad799x_ring_cleanup(struct iio_dev *indio_dev);
-#else /* CONFIG_AD799X_RING_BUFFER */
-
-static inline int
-ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev)
-{
- return 0;
-}
-
-static inline void ad799x_ring_cleanup(struct iio_dev *indio_dev)
-{
-}
-#endif /* CONFIG_AD799X_RING_BUFFER */
-#endif /* _AD799X_H_ */
diff --git a/drivers/staging/iio/adc/ad799x_core.c b/drivers/staging/iio/adc/ad799x_core.c
deleted file mode 100644
index 2b2049c8bc6..00000000000
--- a/drivers/staging/iio/adc/ad799x_core.c
+++ /dev/null
@@ -1,707 +0,0 @@
-/*
- * iio/adc/ad799x.c
- * Copyright (C) 2010-1011 Michael Hennerich, Analog Devices Inc.
- *
- * based on iio/adc/max1363
- * Copyright (C) 2008-2010 Jonathan Cameron
- *
- * based on linux/drivers/i2c/chips/max123x
- * Copyright (C) 2002-2004 Stefan Eletzhofer
- *
- * based on linux/drivers/acron/char/pcf8583.c
- * Copyright (C) 2000 Russell King
- *
- * 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.
- *
- * ad799x.c
- *
- * Support for ad7991, ad7995, ad7999, ad7992, ad7993, ad7994, ad7997,
- * ad7998 and similar chips.
- *
- */
-
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/sysfs.h>
-#include <linux/i2c.h>
-#include <linux/regulator/consumer.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/err.h>
-#include <linux/module.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-#include <linux/iio/events.h>
-#include <linux/iio/buffer.h>
-
-#include "ad799x.h"
-
-/*
- * ad799x register access by I2C
- */
-static int ad799x_i2c_read16(struct ad799x_state *st, u8 reg, u16 *data)
-{
- struct i2c_client *client = st->client;
- int ret = 0;
-
- ret = i2c_smbus_read_word_swapped(client, reg);
- if (ret < 0) {
- dev_err(&client->dev, "I2C read error\n");
- return ret;
- }
-
- *data = (u16)ret;
-
- return 0;
-}
-
-static int ad799x_i2c_read8(struct ad799x_state *st, u8 reg, u8 *data)
-{
- struct i2c_client *client = st->client;
- int ret = 0;
-
- ret = i2c_smbus_read_byte_data(client, reg);
- if (ret < 0) {
- dev_err(&client->dev, "I2C read error\n");
- return ret;
- }
-
- *data = (u8)ret;
-
- return 0;
-}
-
-static int ad799x_i2c_write16(struct ad799x_state *st, u8 reg, u16 data)
-{
- struct i2c_client *client = st->client;
- int ret = 0;
-
- ret = i2c_smbus_write_word_swapped(client, reg, data);
- if (ret < 0)
- dev_err(&client->dev, "I2C write error\n");
-
- return ret;
-}
-
-static int ad799x_i2c_write8(struct ad799x_state *st, u8 reg, u8 data)
-{
- struct i2c_client *client = st->client;
- int ret = 0;
-
- ret = i2c_smbus_write_byte_data(client, reg, data);
- if (ret < 0)
- dev_err(&client->dev, "I2C write error\n");
-
- return ret;
-}
-
-static int ad7997_8_update_scan_mode(struct iio_dev *indio_dev,
- const unsigned long *scan_mask)
-{
- struct ad799x_state *st = iio_priv(indio_dev);
-
- kfree(st->rx_buf);
- st->rx_buf = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
- if (!st->rx_buf)
- return -ENOMEM;
-
- st->transfer_size = bitmap_weight(scan_mask, indio_dev->masklength) * 2;
-
- switch (st->id) {
- case ad7997:
- case ad7998:
- return ad799x_i2c_write16(st, AD7998_CONF_REG,
- st->config | (*scan_mask << AD799X_CHANNEL_SHIFT));
- default:
- break;
- }
-
- return 0;
-}
-
-static int ad799x_scan_direct(struct ad799x_state *st, unsigned ch)
-{
- u16 rxbuf;
- u8 cmd;
- int ret;
-
- switch (st->id) {
- case ad7991:
- case ad7995:
- case ad7999:
- cmd = st->config | ((1 << ch) << AD799X_CHANNEL_SHIFT);
- break;
- case ad7992:
- case ad7993:
- case ad7994:
- cmd = (1 << ch) << AD799X_CHANNEL_SHIFT;
- break;
- case ad7997:
- case ad7998:
- cmd = (ch << AD799X_CHANNEL_SHIFT) | AD7997_8_READ_SINGLE;
- break;
- default:
- return -EINVAL;
- }
-
- ret = ad799x_i2c_read16(st, cmd, &rxbuf);
- if (ret < 0)
- return ret;
-
- return rxbuf;
-}
-
-static int ad799x_read_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int *val,
- int *val2,
- long m)
-{
- int ret;
- struct ad799x_state *st = iio_priv(indio_dev);
- unsigned int scale_uv;
-
- switch (m) {
- case IIO_CHAN_INFO_RAW:
- mutex_lock(&indio_dev->mlock);
- if (iio_buffer_enabled(indio_dev))
- ret = -EBUSY;
- else
- ret = ad799x_scan_direct(st, chan->scan_index);
- mutex_unlock(&indio_dev->mlock);
-
- if (ret < 0)
- return ret;
- *val = (ret >> chan->scan_type.shift) &
- RES_MASK(chan->scan_type.realbits);
- return IIO_VAL_INT;
- case IIO_CHAN_INFO_SCALE:
- scale_uv = (st->int_vref_mv * 1000) >> chan->scan_type.realbits;
- *val = scale_uv / 1000;
- *val2 = (scale_uv % 1000) * 1000;
- return IIO_VAL_INT_PLUS_MICRO;
- }
- return -EINVAL;
-}
-static const unsigned int ad7998_frequencies[] = {
- [AD7998_CYC_DIS] = 0,
- [AD7998_CYC_TCONF_32] = 15625,
- [AD7998_CYC_TCONF_64] = 7812,
- [AD7998_CYC_TCONF_128] = 3906,
- [AD7998_CYC_TCONF_512] = 976,
- [AD7998_CYC_TCONF_1024] = 488,
- [AD7998_CYC_TCONF_2048] = 244,
-};
-static ssize_t ad799x_read_frequency(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct ad799x_state *st = iio_priv(indio_dev);
-
- int ret;
- u8 val;
- ret = ad799x_i2c_read8(st, AD7998_CYCLE_TMR_REG, &val);
- if (ret)
- return ret;
-
- val &= AD7998_CYC_MASK;
-
- return sprintf(buf, "%u\n", ad7998_frequencies[val]);
-}
-
-static ssize_t ad799x_write_frequency(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct ad799x_state *st = iio_priv(indio_dev);
-
- long val;
- int ret, i;
- u8 t;
-
- ret = kstrtol(buf, 10, &val);
- if (ret)
- return ret;
-
- mutex_lock(&indio_dev->mlock);
- ret = ad799x_i2c_read8(st, AD7998_CYCLE_TMR_REG, &t);
- if (ret)
- goto error_ret_mutex;
- /* Wipe the bits clean */
- t &= ~AD7998_CYC_MASK;
-
- for (i = 0; i < ARRAY_SIZE(ad7998_frequencies); i++)
- if (val == ad7998_frequencies[i])
- break;
- if (i == ARRAY_SIZE(ad7998_frequencies)) {
- ret = -EINVAL;
- goto error_ret_mutex;
- }
- t |= i;
- ret = ad799x_i2c_write8(st, AD7998_CYCLE_TMR_REG, t);
-
-error_ret_mutex:
- mutex_unlock(&indio_dev->mlock);
-
- return ret ? ret : len;
-}
-
-static int ad799x_read_event_config(struct iio_dev *indio_dev,
- u64 event_code)
-{
- return 1;
-}
-
-static const u8 ad799x_threshold_addresses[][2] = {
- { AD7998_DATALOW_CH1_REG, AD7998_DATAHIGH_CH1_REG },
- { AD7998_DATALOW_CH2_REG, AD7998_DATAHIGH_CH2_REG },
- { AD7998_DATALOW_CH3_REG, AD7998_DATAHIGH_CH3_REG },
- { AD7998_DATALOW_CH4_REG, AD7998_DATAHIGH_CH4_REG },
-};
-
-static int ad799x_write_event_value(struct iio_dev *indio_dev,
- u64 event_code,
- int val)
-{
- int ret;
- struct ad799x_state *st = iio_priv(indio_dev);
- int direction = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
- IIO_EV_DIR_FALLING);
- int number = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
-
- mutex_lock(&indio_dev->mlock);
- ret = ad799x_i2c_write16(st,
- ad799x_threshold_addresses[number][direction],
- val);
- mutex_unlock(&indio_dev->mlock);
-
- return ret;
-}
-
-static int ad799x_read_event_value(struct iio_dev *indio_dev,
- u64 event_code,
- int *val)
-{
- int ret;
- struct ad799x_state *st = iio_priv(indio_dev);
- int direction = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
- IIO_EV_DIR_FALLING);
- int number = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
- u16 valin;
-
- mutex_lock(&indio_dev->mlock);
- ret = ad799x_i2c_read16(st,
- ad799x_threshold_addresses[number][direction],
- &valin);
- mutex_unlock(&indio_dev->mlock);
- if (ret < 0)
- return ret;
- *val = valin;
-
- return 0;
-}
-
-static ssize_t ad799x_read_channel_config(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct ad799x_state *st = iio_priv(indio_dev);
- struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
- int ret;
- u16 val;
- ret = ad799x_i2c_read16(st, this_attr->address, &val);
- if (ret)
- return ret;
-
- return sprintf(buf, "%d\n", val);
-}
-
-static ssize_t ad799x_write_channel_config(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct ad799x_state *st = iio_priv(indio_dev);
- struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
- long val;
- int ret;
-
- ret = kstrtol(buf, 10, &val);
- if (ret)
- return ret;
-
- mutex_lock(&indio_dev->mlock);
- ret = ad799x_i2c_write16(st, this_attr->address, val);
- mutex_unlock(&indio_dev->mlock);
-
- return ret ? ret : len;
-}
-
-static irqreturn_t ad799x_event_handler(int irq, void *private)
-{
- struct iio_dev *indio_dev = private;
- struct ad799x_state *st = iio_priv(private);
- u8 status;
- int i, ret;
-
- ret = ad799x_i2c_read8(st, AD7998_ALERT_STAT_REG, &status);
- if (ret)
- goto done;
-
- if (!status)
- goto done;
-
- ad799x_i2c_write8(st, AD7998_ALERT_STAT_REG, AD7998_ALERT_STAT_CLEAR);
-
- for (i = 0; i < 8; i++) {
- if (status & (1 << i))
- iio_push_event(indio_dev,
- i & 0x1 ?
- IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE,
- (i >> 1),
- IIO_EV_TYPE_THRESH,
- IIO_EV_DIR_RISING) :
- IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE,
- (i >> 1),
- IIO_EV_TYPE_THRESH,
- IIO_EV_DIR_FALLING),
- iio_get_time_ns());
- }
-
-done:
- return IRQ_HANDLED;
-}
-
-static IIO_DEVICE_ATTR(in_voltage0_thresh_both_hyst_raw,
- S_IRUGO | S_IWUSR,
- ad799x_read_channel_config,
- ad799x_write_channel_config,
- AD7998_HYST_CH1_REG);
-
-static IIO_DEVICE_ATTR(in_voltage1_thresh_both_hyst_raw,
- S_IRUGO | S_IWUSR,
- ad799x_read_channel_config,
- ad799x_write_channel_config,
- AD7998_HYST_CH2_REG);
-
-static IIO_DEVICE_ATTR(in_voltage2_thresh_both_hyst_raw,
- S_IRUGO | S_IWUSR,
- ad799x_read_channel_config,
- ad799x_write_channel_config,
- AD7998_HYST_CH3_REG);
-
-static IIO_DEVICE_ATTR(in_voltage3_thresh_both_hyst_raw,
- S_IRUGO | S_IWUSR,
- ad799x_read_channel_config,
- ad799x_write_channel_config,
- AD7998_HYST_CH4_REG);
-
-static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
- ad799x_read_frequency,
- ad799x_write_frequency);
-static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("15625 7812 3906 1953 976 488 244 0");
-
-static struct attribute *ad7993_4_7_8_event_attributes[] = {
- &iio_dev_attr_in_voltage0_thresh_both_hyst_raw.dev_attr.attr,
- &iio_dev_attr_in_voltage1_thresh_both_hyst_raw.dev_attr.attr,
- &iio_dev_attr_in_voltage2_thresh_both_hyst_raw.dev_attr.attr,
- &iio_dev_attr_in_voltage3_thresh_both_hyst_raw.dev_attr.attr,
- &iio_dev_attr_sampling_frequency.dev_attr.attr,
- &iio_const_attr_sampling_frequency_available.dev_attr.attr,
- NULL,
-};
-
-static struct attribute_group ad7993_4_7_8_event_attrs_group = {
- .attrs = ad7993_4_7_8_event_attributes,
- .name = "events",
-};
-
-static struct attribute *ad7992_event_attributes[] = {
- &iio_dev_attr_in_voltage0_thresh_both_hyst_raw.dev_attr.attr,
- &iio_dev_attr_in_voltage1_thresh_both_hyst_raw.dev_attr.attr,
- &iio_dev_attr_sampling_frequency.dev_attr.attr,
- &iio_const_attr_sampling_frequency_available.dev_attr.attr,
- NULL,
-};
-
-static struct attribute_group ad7992_event_attrs_group = {
- .attrs = ad7992_event_attributes,
- .name = "events",
-};
-
-static const struct iio_info ad7991_info = {
- .read_raw = &ad799x_read_raw,
- .driver_module = THIS_MODULE,
-};
-
-static const struct iio_info ad7992_info = {
- .read_raw = &ad799x_read_raw,
- .event_attrs = &ad7992_event_attrs_group,
- .read_event_config = &ad799x_read_event_config,
- .read_event_value = &ad799x_read_event_value,
- .write_event_value = &ad799x_write_event_value,
- .driver_module = THIS_MODULE,
-};
-
-static const struct iio_info ad7993_4_7_8_info = {
- .read_raw = &ad799x_read_raw,
- .event_attrs = &ad7993_4_7_8_event_attrs_group,
- .read_event_config = &ad799x_read_event_config,
- .read_event_value = &ad799x_read_event_value,
- .write_event_value = &ad799x_write_event_value,
- .driver_module = THIS_MODULE,
- .update_scan_mode = ad7997_8_update_scan_mode,
-};
-
-#define AD799X_EV_MASK (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | \
- IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING))
-
-#define AD799X_CHANNEL(_index, _realbits, _evmask) { \
- .type = IIO_VOLTAGE, \
- .indexed = 1, \
- .channel = (_index), \
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
- .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
- .scan_index = (_index), \
- .scan_type = IIO_ST('u', _realbits, 16, 12 - (_realbits)), \
- .event_mask = (_evmask), \
-}
-
-static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
- [ad7991] = {
- .channel = {
- AD799X_CHANNEL(0, 12, 0),
- AD799X_CHANNEL(1, 12, 0),
- AD799X_CHANNEL(2, 12, 0),
- AD799X_CHANNEL(3, 12, 0),
- IIO_CHAN_SOFT_TIMESTAMP(4),
- },
- .num_channels = 5,
- .info = &ad7991_info,
- },
- [ad7995] = {
- .channel = {
- AD799X_CHANNEL(0, 10, 0),
- AD799X_CHANNEL(1, 10, 0),
- AD799X_CHANNEL(2, 10, 0),
- AD799X_CHANNEL(3, 10, 0),
- IIO_CHAN_SOFT_TIMESTAMP(4),
- },
- .num_channels = 5,
- .info = &ad7991_info,
- },
- [ad7999] = {
- .channel = {
- AD799X_CHANNEL(0, 8, 0),
- AD799X_CHANNEL(1, 8, 0),
- AD799X_CHANNEL(2, 8, 0),
- AD799X_CHANNEL(3, 8, 0),
- IIO_CHAN_SOFT_TIMESTAMP(4),
- },
- .num_channels = 5,
- .info = &ad7991_info,
- },
- [ad7992] = {
- .channel = {
- AD799X_CHANNEL(0, 12, AD799X_EV_MASK),
- AD799X_CHANNEL(1, 12, AD799X_EV_MASK),
- IIO_CHAN_SOFT_TIMESTAMP(3),
- },
- .num_channels = 3,
- .default_config = AD7998_ALERT_EN,
- .info = &ad7992_info,
- },
- [ad7993] = {
- .channel = {
- AD799X_CHANNEL(0, 10, AD799X_EV_MASK),
- AD799X_CHANNEL(1, 10, AD799X_EV_MASK),
- AD799X_CHANNEL(2, 10, AD799X_EV_MASK),
- AD799X_CHANNEL(3, 10, AD799X_EV_MASK),
- IIO_CHAN_SOFT_TIMESTAMP(4),
- },
- .num_channels = 5,
- .default_config = AD7998_ALERT_EN,
- .info = &ad7993_4_7_8_info,
- },
- [ad7994] = {
- .channel = {
- AD799X_CHANNEL(0, 12, AD799X_EV_MASK),
- AD799X_CHANNEL(1, 12, AD799X_EV_MASK),
- AD799X_CHANNEL(2, 12, AD799X_EV_MASK),
- AD799X_CHANNEL(3, 12, AD799X_EV_MASK),
- IIO_CHAN_SOFT_TIMESTAMP(4),
- },
- .num_channels = 5,
- .default_config = AD7998_ALERT_EN,
- .info = &ad7993_4_7_8_info,
- },
- [ad7997] = {
- .channel = {
- AD799X_CHANNEL(0, 10, AD799X_EV_MASK),
- AD799X_CHANNEL(1, 10, AD799X_EV_MASK),
- AD799X_CHANNEL(2, 10, AD799X_EV_MASK),
- AD799X_CHANNEL(3, 10, AD799X_EV_MASK),
- AD799X_CHANNEL(4, 10, 0),
- AD799X_CHANNEL(5, 10, 0),
- AD799X_CHANNEL(6, 10, 0),
- AD799X_CHANNEL(7, 10, 0),
- IIO_CHAN_SOFT_TIMESTAMP(8),
- },
- .num_channels = 9,
- .default_config = AD7998_ALERT_EN,
- .info = &ad7993_4_7_8_info,
- },
- [ad7998] = {
- .channel = {
- AD799X_CHANNEL(0, 12, AD799X_EV_MASK),
- AD799X_CHANNEL(1, 12, AD799X_EV_MASK),
- AD799X_CHANNEL(2, 12, AD799X_EV_MASK),
- AD799X_CHANNEL(3, 12, AD799X_EV_MASK),
- AD799X_CHANNEL(4, 12, 0),
- AD799X_CHANNEL(5, 12, 0),
- AD799X_CHANNEL(6, 12, 0),
- AD799X_CHANNEL(7, 12, 0),
- IIO_CHAN_SOFT_TIMESTAMP(8),
- },
- .num_channels = 9,
- .default_config = AD7998_ALERT_EN,
- .info = &ad7993_4_7_8_info,
- },
-};
-
-static int ad799x_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- int ret;
- struct ad799x_platform_data *pdata = client->dev.platform_data;
- struct ad799x_state *st;
- struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
-
- if (indio_dev == NULL)
- return -ENOMEM;
-
- st = iio_priv(indio_dev);
- /* this is only used for device removal purposes */
- i2c_set_clientdata(client, indio_dev);
-
- st->id = id->driver_data;
- st->chip_info = &ad799x_chip_info_tbl[st->id];
- st->config = st->chip_info->default_config;
-
- /* TODO: Add pdata options for filtering and bit delay */
-
- if (!pdata)
- return -EINVAL;
-
- st->int_vref_mv = pdata->vref_mv;
-
- st->reg = regulator_get(&client->dev, "vcc");
- if (!IS_ERR(st->reg)) {
- ret = regulator_enable(st->reg);
- if (ret)
- goto error_put_reg;
- }
- st->client = client;
-
- indio_dev->dev.parent = &client->dev;
- indio_dev->name = id->name;
- indio_dev->info = st->chip_info->info;
-
- indio_dev->modes = INDIO_DIRECT_MODE;
- indio_dev->channels = st->chip_info->channel;
- indio_dev->num_channels = st->chip_info->num_channels;
-
- ret = ad799x_register_ring_funcs_and_init(indio_dev);
- if (ret)
- goto error_disable_reg;
-
- if (client->irq > 0) {
- ret = request_threaded_irq(client->irq,
- NULL,
- ad799x_event_handler,
- IRQF_TRIGGER_FALLING |
- IRQF_ONESHOT,
- client->name,
- indio_dev);
- if (ret)
- goto error_cleanup_ring;
- }
- ret = iio_device_register(indio_dev);
- if (ret)
- goto error_free_irq;
-
- return 0;
-
-error_free_irq:
- free_irq(client->irq, indio_dev);
-error_cleanup_ring:
- ad799x_ring_cleanup(indio_dev);
-error_disable_reg:
- if (!IS_ERR(st->reg))
- regulator_disable(st->reg);
-error_put_reg:
- if (!IS_ERR(st->reg))
- regulator_put(st->reg);
- iio_device_free(indio_dev);
-
- return ret;
-}
-
-static int ad799x_remove(struct i2c_client *client)
-{
- struct iio_dev *indio_dev = i2c_get_clientdata(client);
- struct ad799x_state *st = iio_priv(indio_dev);
-
- iio_device_unregister(indio_dev);
- if (client->irq > 0)
- free_irq(client->irq, indio_dev);
-
- ad799x_ring_cleanup(indio_dev);
- if (!IS_ERR(st->reg)) {
- regulator_disable(st->reg);
- regulator_put(st->reg);
- }
- kfree(st->rx_buf);
- iio_device_free(indio_dev);
-
- return 0;
-}
-
-static const struct i2c_device_id ad799x_id[] = {
- { "ad7991", ad7991 },
- { "ad7995", ad7995 },
- { "ad7999", ad7999 },
- { "ad7992", ad7992 },
- { "ad7993", ad7993 },
- { "ad7994", ad7994 },
- { "ad7997", ad7997 },
- { "ad7998", ad7998 },
- {}
-};
-
-MODULE_DEVICE_TABLE(i2c, ad799x_id);
-
-static struct i2c_driver ad799x_driver = {
- .driver = {
- .name = "ad799x",
- },
- .probe = ad799x_probe,
- .remove = ad799x_remove,
- .id_table = ad799x_id,
-};
-module_i2c_driver(ad799x_driver);
-
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
-MODULE_DESCRIPTION("Analog Devices AD799x ADC");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c
deleted file mode 100644
index c2ebae12ee1..00000000000
--- a/drivers/staging/iio/adc/ad799x_ring.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2010-2012 Michael Hennerich, Analog Devices Inc.
- * Copyright (C) 2008-2010 Jonathan Cameron
- *
- * 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.
- *
- * ad799x_ring.c
- */
-
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/i2c.h>
-#include <linux/bitops.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/buffer.h>
-#include <linux/iio/trigger_consumer.h>
-#include <linux/iio/triggered_buffer.h>
-
-#include "ad799x.h"
-
-/**
- * ad799x_trigger_handler() bh of trigger launched polling to ring buffer
- *
- * Currently there is no option in this driver to disable the saving of
- * timestamps within the ring.
- **/
-
-static irqreturn_t ad799x_trigger_handler(int irq, void *p)
-{
- struct iio_poll_func *pf = p;
- struct iio_dev *indio_dev = pf->indio_dev;
- struct ad799x_state *st = iio_priv(indio_dev);
- s64 time_ns;
- int b_sent;
- u8 cmd;
-
- switch (st->id) {
- case ad7991:
- case ad7995:
- case ad7999:
- cmd = st->config |
- (*indio_dev->active_scan_mask << AD799X_CHANNEL_SHIFT);
- break;
- case ad7992:
- case ad7993:
- case ad7994:
- cmd = (*indio_dev->active_scan_mask << AD799X_CHANNEL_SHIFT) |
- AD7998_CONV_RES_REG;
- break;
- case ad7997:
- case ad7998:
- cmd = AD7997_8_READ_SEQUENCE | AD7998_CONV_RES_REG;
- break;
- default:
- cmd = 0;
- }
-
- b_sent = i2c_smbus_read_i2c_block_data(st->client,
- cmd, st->transfer_size, st->rx_buf);
- if (b_sent < 0)
- goto out;
-
- time_ns = iio_get_time_ns();
-
- if (indio_dev->scan_timestamp)
- memcpy(st->rx_buf + indio_dev->scan_bytes - sizeof(s64),
- &time_ns, sizeof(time_ns));
-
- iio_push_to_buffers(indio_dev, st->rx_buf);
-out:
- iio_trigger_notify_done(indio_dev->trig);
-
- return IRQ_HANDLED;
-}
-
-int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev)
-{
- return iio_triggered_buffer_setup(indio_dev, NULL,
- &ad799x_trigger_handler, NULL);
-}
-
-void ad799x_ring_cleanup(struct iio_dev *indio_dev)
-{
- iio_triggered_buffer_cleanup(indio_dev);
-}
diff --git a/drivers/staging/iio/adc/lpc32xx_adc.c b/drivers/staging/iio/adc/lpc32xx_adc.c
index 9a4bb0999b5..a876ce75535 100644
--- a/drivers/staging/iio/adc/lpc32xx_adc.c
+++ b/drivers/staging/iio/adc/lpc32xx_adc.c
@@ -137,43 +137,39 @@ static int lpc32xx_adc_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "failed to get platform I/O memory\n");
- retval = -EBUSY;
- goto errout1;
+ return -EBUSY;
}
- iodev = iio_device_alloc(sizeof(struct lpc32xx_adc_info));
- if (!iodev) {
- dev_err(&pdev->dev, "failed allocating iio device\n");
- retval = -ENOMEM;
- goto errout1;
- }
+ iodev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));
+ if (!iodev)
+ return -ENOMEM;
info = iio_priv(iodev);
- info->adc_base = ioremap(res->start, resource_size(res));
+ info->adc_base = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
if (!info->adc_base) {
dev_err(&pdev->dev, "failed mapping memory\n");
- retval = -EBUSY;
- goto errout2;
+ return -EBUSY;
}
- info->clk = clk_get(&pdev->dev, NULL);
+ info->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(info->clk)) {
dev_err(&pdev->dev, "failed getting clock\n");
- goto errout3;
+ return PTR_ERR(info->clk);
}
irq = platform_get_irq(pdev, 0);
- if ((irq < 0) || (irq >= NR_IRQS)) {
+ if (irq <= 0) {
dev_err(&pdev->dev, "failed getting interrupt resource\n");
- retval = -EINVAL;
- goto errout4;
+ return -EINVAL;
}
- retval = request_irq(irq, lpc32xx_adc_isr, 0, MOD_NAME, info);
+ retval = devm_request_irq(&pdev->dev, irq, lpc32xx_adc_isr, 0,
+ MOD_NAME, info);
if (retval < 0) {
dev_err(&pdev->dev, "failed requesting interrupt\n");
- goto errout4;
+ return retval;
}
platform_set_drvdata(pdev, iodev);
@@ -187,39 +183,13 @@ static int lpc32xx_adc_probe(struct platform_device *pdev)
iodev->channels = lpc32xx_adc_iio_channels;
iodev->num_channels = ARRAY_SIZE(lpc32xx_adc_iio_channels);
- retval = iio_device_register(iodev);
+ retval = devm_iio_device_register(&pdev->dev, iodev);
if (retval)
- goto errout5;
+ return retval;
dev_info(&pdev->dev, "LPC32XX ADC driver loaded, IRQ %d\n", irq);
return 0;
-
-errout5:
- free_irq(irq, info);
-errout4:
- clk_put(info->clk);
-errout3:
- iounmap(info->adc_base);
-errout2:
- iio_device_free(iodev);
-errout1:
- return retval;
-}
-
-static int lpc32xx_adc_remove(struct platform_device *pdev)
-{
- struct iio_dev *iodev = platform_get_drvdata(pdev);
- struct lpc32xx_adc_info *info = iio_priv(iodev);
- int irq = platform_get_irq(pdev, 0);
-
- iio_device_unregister(iodev);
- free_irq(irq, info);
- clk_put(info->clk);
- iounmap(info->adc_base);
- iio_device_free(iodev);
-
- return 0;
}
#ifdef CONFIG_OF
@@ -232,7 +202,6 @@ MODULE_DEVICE_TABLE(of, lpc32xx_adc_match);
static struct platform_driver lpc32xx_adc_driver = {
.probe = lpc32xx_adc_probe,
- .remove = lpc32xx_adc_remove,
.driver = {
.name = MOD_NAME,
.owner = THIS_MODULE,
diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c
index d92c97a59d6..52d7517b342 100644
--- a/drivers/staging/iio/adc/mxs-lradc.c
+++ b/drivers/staging/iio/adc/mxs-lradc.c
@@ -35,8 +35,10 @@
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/input.h>
+#include <linux/clk.h>
#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
#include <linux/iio/trigger.h>
#include <linux/iio/trigger_consumer.h>
@@ -110,16 +112,59 @@ static const char * const mx28_lradc_irq_names[] = {
struct mxs_lradc_of_config {
const int irq_count;
const char * const *irq_name;
+ const uint32_t *vref_mv;
+};
+
+#define VREF_MV_BASE 1850
+
+static const uint32_t mx23_vref_mv[LRADC_MAX_TOTAL_CHANS] = {
+ VREF_MV_BASE, /* CH0 */
+ VREF_MV_BASE, /* CH1 */
+ VREF_MV_BASE, /* CH2 */
+ VREF_MV_BASE, /* CH3 */
+ VREF_MV_BASE, /* CH4 */
+ VREF_MV_BASE, /* CH5 */
+ VREF_MV_BASE * 2, /* CH6 VDDIO */
+ VREF_MV_BASE * 4, /* CH7 VBATT */
+ VREF_MV_BASE, /* CH8 Temp sense 0 */
+ VREF_MV_BASE, /* CH9 Temp sense 1 */
+ VREF_MV_BASE, /* CH10 */
+ VREF_MV_BASE, /* CH11 */
+ VREF_MV_BASE, /* CH12 USB_DP */
+ VREF_MV_BASE, /* CH13 USB_DN */
+ VREF_MV_BASE, /* CH14 VBG */
+ VREF_MV_BASE * 4, /* CH15 VDD5V */
+};
+
+static const uint32_t mx28_vref_mv[LRADC_MAX_TOTAL_CHANS] = {
+ VREF_MV_BASE, /* CH0 */
+ VREF_MV_BASE, /* CH1 */
+ VREF_MV_BASE, /* CH2 */
+ VREF_MV_BASE, /* CH3 */
+ VREF_MV_BASE, /* CH4 */
+ VREF_MV_BASE, /* CH5 */
+ VREF_MV_BASE, /* CH6 */
+ VREF_MV_BASE * 4, /* CH7 VBATT */
+ VREF_MV_BASE, /* CH8 Temp sense 0 */
+ VREF_MV_BASE, /* CH9 Temp sense 1 */
+ VREF_MV_BASE * 2, /* CH10 VDDIO */
+ VREF_MV_BASE, /* CH11 VTH */
+ VREF_MV_BASE * 2, /* CH12 VDDA */
+ VREF_MV_BASE, /* CH13 VDDD */
+ VREF_MV_BASE, /* CH14 VBG */
+ VREF_MV_BASE * 4, /* CH15 VDD5V */
};
static const struct mxs_lradc_of_config mxs_lradc_of_config[] = {
[IMX23_LRADC] = {
.irq_count = ARRAY_SIZE(mx23_lradc_irq_names),
.irq_name = mx23_lradc_irq_names,
+ .vref_mv = mx23_vref_mv,
},
[IMX28_LRADC] = {
.irq_count = ARRAY_SIZE(mx28_lradc_irq_names),
.irq_name = mx28_lradc_irq_names,
+ .vref_mv = mx28_vref_mv,
},
};
@@ -129,11 +174,34 @@ enum mxs_lradc_ts {
MXS_LRADC_TOUCHSCREEN_5WIRE,
};
+/*
+ * Touchscreen handling
+ */
+enum lradc_ts_plate {
+ LRADC_TOUCH = 0,
+ LRADC_SAMPLE_X,
+ LRADC_SAMPLE_Y,
+ LRADC_SAMPLE_PRESSURE,
+ LRADC_SAMPLE_VALID,
+};
+
+enum mxs_lradc_divbytwo {
+ MXS_LRADC_DIV_DISABLED = 0,
+ MXS_LRADC_DIV_ENABLED,
+};
+
+struct mxs_lradc_scale {
+ unsigned int integer;
+ unsigned int nano;
+};
+
struct mxs_lradc {
struct device *dev;
void __iomem *base;
int irq[13];
+ struct clk *clk;
+
uint32_t *buffer;
struct iio_trigger *trig;
@@ -141,6 +209,10 @@ struct mxs_lradc {
struct completion completion;
+ const uint32_t *vref_mv;
+ struct mxs_lradc_scale scale_avail[LRADC_MAX_TOTAL_CHANS][2];
+ unsigned long is_divided;
+
/*
* Touchscreen LRADC channels receives a private slot in the CTRL4
* register, the slot #7. Therefore only 7 slots instead of 8 in the
@@ -169,35 +241,67 @@ struct mxs_lradc {
#define CHAN_MASK_TOUCHSCREEN_4WIRE (0xf << 2)
#define CHAN_MASK_TOUCHSCREEN_5WIRE (0x1f << 2)
enum mxs_lradc_ts use_touchscreen;
- bool stop_touchscreen;
bool use_touchbutton;
struct input_dev *ts_input;
- struct work_struct ts_work;
+
+ enum mxs_lradc_id soc;
+ enum lradc_ts_plate cur_plate; /* statemachine */
+ bool ts_valid;
+ unsigned ts_x_pos;
+ unsigned ts_y_pos;
+ unsigned ts_pressure;
+
+ /* handle touchscreen's physical behaviour */
+ /* samples per coordinate */
+ unsigned over_sample_cnt;
+ /* time clocks between samples */
+ unsigned over_sample_delay;
+ /* time in clocks to wait after the plates where switched */
+ unsigned settling_delay;
};
#define LRADC_CTRL0 0x00
-#define LRADC_CTRL0_TOUCH_DETECT_ENABLE (1 << 23)
-#define LRADC_CTRL0_TOUCH_SCREEN_TYPE (1 << 22)
-#define LRADC_CTRL0_YNNSW /* YM */ (1 << 21)
-#define LRADC_CTRL0_YPNSW /* YP */ (1 << 20)
-#define LRADC_CTRL0_YPPSW /* YP */ (1 << 19)
-#define LRADC_CTRL0_XNNSW /* XM */ (1 << 18)
-#define LRADC_CTRL0_XNPSW /* XM */ (1 << 17)
-#define LRADC_CTRL0_XPPSW /* XP */ (1 << 16)
-#define LRADC_CTRL0_PLATE_MASK (0x3f << 16)
+# define LRADC_CTRL0_MX28_TOUCH_DETECT_ENABLE (1 << 23)
+# define LRADC_CTRL0_MX28_TOUCH_SCREEN_TYPE (1 << 22)
+# define LRADC_CTRL0_MX28_YNNSW /* YM */ (1 << 21)
+# define LRADC_CTRL0_MX28_YPNSW /* YP */ (1 << 20)
+# define LRADC_CTRL0_MX28_YPPSW /* YP */ (1 << 19)
+# define LRADC_CTRL0_MX28_XNNSW /* XM */ (1 << 18)
+# define LRADC_CTRL0_MX28_XNPSW /* XM */ (1 << 17)
+# define LRADC_CTRL0_MX28_XPPSW /* XP */ (1 << 16)
+
+# define LRADC_CTRL0_MX23_TOUCH_DETECT_ENABLE (1 << 20)
+# define LRADC_CTRL0_MX23_YM (1 << 19)
+# define LRADC_CTRL0_MX23_XM (1 << 18)
+# define LRADC_CTRL0_MX23_YP (1 << 17)
+# define LRADC_CTRL0_MX23_XP (1 << 16)
+
+# define LRADC_CTRL0_MX28_PLATE_MASK \
+ (LRADC_CTRL0_MX28_TOUCH_DETECT_ENABLE | \
+ LRADC_CTRL0_MX28_YNNSW | LRADC_CTRL0_MX28_YPNSW | \
+ LRADC_CTRL0_MX28_YPPSW | LRADC_CTRL0_MX28_XNNSW | \
+ LRADC_CTRL0_MX28_XNPSW | LRADC_CTRL0_MX28_XPPSW)
+
+# define LRADC_CTRL0_MX23_PLATE_MASK \
+ (LRADC_CTRL0_MX23_TOUCH_DETECT_ENABLE | \
+ LRADC_CTRL0_MX23_YM | LRADC_CTRL0_MX23_XM | \
+ LRADC_CTRL0_MX23_YP | LRADC_CTRL0_MX23_XP)
#define LRADC_CTRL1 0x10
#define LRADC_CTRL1_TOUCH_DETECT_IRQ_EN (1 << 24)
#define LRADC_CTRL1_LRADC_IRQ_EN(n) (1 << ((n) + 16))
-#define LRADC_CTRL1_LRADC_IRQ_EN_MASK (0x1fff << 16)
+#define LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK (0x1fff << 16)
+#define LRADC_CTRL1_MX23_LRADC_IRQ_EN_MASK (0x01ff << 16)
#define LRADC_CTRL1_LRADC_IRQ_EN_OFFSET 16
#define LRADC_CTRL1_TOUCH_DETECT_IRQ (1 << 8)
#define LRADC_CTRL1_LRADC_IRQ(n) (1 << (n))
-#define LRADC_CTRL1_LRADC_IRQ_MASK 0x1fff
+#define LRADC_CTRL1_MX28_LRADC_IRQ_MASK 0x1fff
+#define LRADC_CTRL1_MX23_LRADC_IRQ_MASK 0x01ff
#define LRADC_CTRL1_LRADC_IRQ_OFFSET 0
#define LRADC_CTRL2 0x20
+#define LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET 24
#define LRADC_CTRL2_TEMPSENSE_PWD (1 << 15)
#define LRADC_STATUS 0x40
@@ -207,47 +311,518 @@ struct mxs_lradc {
#define LRADC_CH_ACCUMULATE (1 << 29)
#define LRADC_CH_NUM_SAMPLES_MASK (0x1f << 24)
#define LRADC_CH_NUM_SAMPLES_OFFSET 24
+#define LRADC_CH_NUM_SAMPLES(x) \
+ ((x) << LRADC_CH_NUM_SAMPLES_OFFSET)
#define LRADC_CH_VALUE_MASK 0x3ffff
#define LRADC_CH_VALUE_OFFSET 0
#define LRADC_DELAY(n) (0xd0 + (0x10 * (n)))
#define LRADC_DELAY_TRIGGER_LRADCS_MASK (0xff << 24)
#define LRADC_DELAY_TRIGGER_LRADCS_OFFSET 24
+#define LRADC_DELAY_TRIGGER(x) \
+ (((x) << LRADC_DELAY_TRIGGER_LRADCS_OFFSET) & \
+ LRADC_DELAY_TRIGGER_LRADCS_MASK)
#define LRADC_DELAY_KICK (1 << 20)
#define LRADC_DELAY_TRIGGER_DELAYS_MASK (0xf << 16)
#define LRADC_DELAY_TRIGGER_DELAYS_OFFSET 16
+#define LRADC_DELAY_TRIGGER_DELAYS(x) \
+ (((x) << LRADC_DELAY_TRIGGER_DELAYS_OFFSET) & \
+ LRADC_DELAY_TRIGGER_DELAYS_MASK)
#define LRADC_DELAY_LOOP_COUNT_MASK (0x1f << 11)
#define LRADC_DELAY_LOOP_COUNT_OFFSET 11
+#define LRADC_DELAY_LOOP(x) \
+ (((x) << LRADC_DELAY_LOOP_COUNT_OFFSET) & \
+ LRADC_DELAY_LOOP_COUNT_MASK)
#define LRADC_DELAY_DELAY_MASK 0x7ff
#define LRADC_DELAY_DELAY_OFFSET 0
+#define LRADC_DELAY_DELAY(x) \
+ (((x) << LRADC_DELAY_DELAY_OFFSET) & \
+ LRADC_DELAY_DELAY_MASK)
#define LRADC_CTRL4 0x140
#define LRADC_CTRL4_LRADCSELECT_MASK(n) (0xf << ((n) * 4))
#define LRADC_CTRL4_LRADCSELECT_OFFSET(n) ((n) * 4)
+#define LRADC_RESOLUTION 12
+#define LRADC_SINGLE_SAMPLE_MASK ((1 << LRADC_RESOLUTION) - 1)
+
+static void mxs_lradc_reg_set(struct mxs_lradc *lradc, u32 val, u32 reg)
+{
+ writel(val, lradc->base + reg + STMP_OFFSET_REG_SET);
+}
+
+static void mxs_lradc_reg_clear(struct mxs_lradc *lradc, u32 val, u32 reg)
+{
+ writel(val, lradc->base + reg + STMP_OFFSET_REG_CLR);
+}
+
+static void mxs_lradc_reg_wrt(struct mxs_lradc *lradc, u32 val, u32 reg)
+{
+ writel(val, lradc->base + reg);
+}
+
+static u32 mxs_lradc_plate_mask(struct mxs_lradc *lradc)
+{
+ if (lradc->soc == IMX23_LRADC)
+ return LRADC_CTRL0_MX23_PLATE_MASK;
+ else
+ return LRADC_CTRL0_MX28_PLATE_MASK;
+}
+
+static u32 mxs_lradc_irq_en_mask(struct mxs_lradc *lradc)
+{
+ if (lradc->soc == IMX23_LRADC)
+ return LRADC_CTRL1_MX23_LRADC_IRQ_EN_MASK;
+ else
+ return LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK;
+}
+
+static u32 mxs_lradc_irq_mask(struct mxs_lradc *lradc)
+{
+ if (lradc->soc == IMX23_LRADC)
+ return LRADC_CTRL1_MX23_LRADC_IRQ_MASK;
+ else
+ return LRADC_CTRL1_MX28_LRADC_IRQ_MASK;
+}
+
+static u32 mxs_lradc_touch_detect_bit(struct mxs_lradc *lradc)
+{
+ if (lradc->soc == IMX23_LRADC)
+ return LRADC_CTRL0_MX23_TOUCH_DETECT_ENABLE;
+ else
+ return LRADC_CTRL0_MX28_TOUCH_DETECT_ENABLE;
+}
+
+static u32 mxs_lradc_drive_x_plate(struct mxs_lradc *lradc)
+{
+ if (lradc->soc == IMX23_LRADC)
+ return LRADC_CTRL0_MX23_XP | LRADC_CTRL0_MX23_XM;
+ else
+ return LRADC_CTRL0_MX28_XPPSW | LRADC_CTRL0_MX28_XNNSW;
+}
+
+static u32 mxs_lradc_drive_y_plate(struct mxs_lradc *lradc)
+{
+ if (lradc->soc == IMX23_LRADC)
+ return LRADC_CTRL0_MX23_YP | LRADC_CTRL0_MX23_YM;
+ else
+ return LRADC_CTRL0_MX28_YPPSW | LRADC_CTRL0_MX28_YNNSW;
+}
+
+static u32 mxs_lradc_drive_pressure(struct mxs_lradc *lradc)
+{
+ if (lradc->soc == IMX23_LRADC)
+ return LRADC_CTRL0_MX23_YP | LRADC_CTRL0_MX23_XM;
+ else
+ return LRADC_CTRL0_MX28_YPPSW | LRADC_CTRL0_MX28_XNNSW;
+}
+
+static bool mxs_lradc_check_touch_event(struct mxs_lradc *lradc)
+{
+ return !!(readl(lradc->base + LRADC_STATUS) &
+ LRADC_STATUS_TOUCH_DETECT_RAW);
+}
+
+static void mxs_lradc_setup_ts_channel(struct mxs_lradc *lradc, unsigned ch)
+{
+ /*
+ * prepare for oversampling conversion
+ *
+ * from the datasheet:
+ * "The ACCUMULATE bit in the appropriate channel register
+ * HW_LRADC_CHn must be set to 1 if NUM_SAMPLES is greater then 0;
+ * otherwise, the IRQs will not fire."
+ */
+ mxs_lradc_reg_wrt(lradc, LRADC_CH_ACCUMULATE |
+ LRADC_CH_NUM_SAMPLES(lradc->over_sample_cnt - 1),
+ LRADC_CH(ch));
+
+ /* from the datasheet:
+ * "Software must clear this register in preparation for a
+ * multi-cycle accumulation.
+ */
+ mxs_lradc_reg_clear(lradc, LRADC_CH_VALUE_MASK, LRADC_CH(ch));
+
+ /* prepare the delay/loop unit according to the oversampling count */
+ mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(1 << ch) |
+ LRADC_DELAY_TRIGGER_DELAYS(0) |
+ LRADC_DELAY_LOOP(lradc->over_sample_cnt - 1) |
+ LRADC_DELAY_DELAY(lradc->over_sample_delay - 1),
+ LRADC_DELAY(3));
+
+ mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(2) |
+ LRADC_CTRL1_LRADC_IRQ(3) | LRADC_CTRL1_LRADC_IRQ(4) |
+ LRADC_CTRL1_LRADC_IRQ(5), LRADC_CTRL1);
+
+ /* wake us again, when the complete conversion is done */
+ mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(ch), LRADC_CTRL1);
+ /*
+ * after changing the touchscreen plates setting
+ * the signals need some initial time to settle. Start the
+ * SoC's delay unit and start the conversion later
+ * and automatically.
+ */
+ mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(0) | /* don't trigger ADC */
+ LRADC_DELAY_TRIGGER_DELAYS(1 << 3) | /* trigger DELAY unit#3 */
+ LRADC_DELAY_KICK |
+ LRADC_DELAY_DELAY(lradc->settling_delay),
+ LRADC_DELAY(2));
+}
+
/*
- * Raw I/O operations
+ * Pressure detection is special:
+ * We want to do both required measurements for the pressure detection in
+ * one turn. Use the hardware features to chain both conversions and let the
+ * hardware report one interrupt if both conversions are done
*/
-static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
- const struct iio_chan_spec *chan,
- int *val, int *val2, long m)
+static void mxs_lradc_setup_ts_pressure(struct mxs_lradc *lradc, unsigned ch1,
+ unsigned ch2)
{
- struct mxs_lradc *lradc = iio_priv(iio_dev);
- int ret;
- unsigned long mask;
+ u32 reg;
- if (m != IIO_CHAN_INFO_RAW)
- return -EINVAL;
+ /*
+ * prepare for oversampling conversion
+ *
+ * from the datasheet:
+ * "The ACCUMULATE bit in the appropriate channel register
+ * HW_LRADC_CHn must be set to 1 if NUM_SAMPLES is greater then 0;
+ * otherwise, the IRQs will not fire."
+ */
+ reg = LRADC_CH_ACCUMULATE |
+ LRADC_CH_NUM_SAMPLES(lradc->over_sample_cnt - 1);
+ mxs_lradc_reg_wrt(lradc, reg, LRADC_CH(ch1));
+ mxs_lradc_reg_wrt(lradc, reg, LRADC_CH(ch2));
+
+ /* from the datasheet:
+ * "Software must clear this register in preparation for a
+ * multi-cycle accumulation.
+ */
+ mxs_lradc_reg_clear(lradc, LRADC_CH_VALUE_MASK, LRADC_CH(ch1));
+ mxs_lradc_reg_clear(lradc, LRADC_CH_VALUE_MASK, LRADC_CH(ch2));
+
+ /* prepare the delay/loop unit according to the oversampling count */
+ mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(1 << ch1) |
+ LRADC_DELAY_TRIGGER(1 << ch2) | /* start both channels */
+ LRADC_DELAY_TRIGGER_DELAYS(0) |
+ LRADC_DELAY_LOOP(lradc->over_sample_cnt - 1) |
+ LRADC_DELAY_DELAY(lradc->over_sample_delay - 1),
+ LRADC_DELAY(3));
+
+ mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(2) |
+ LRADC_CTRL1_LRADC_IRQ(3) | LRADC_CTRL1_LRADC_IRQ(4) |
+ LRADC_CTRL1_LRADC_IRQ(5), LRADC_CTRL1);
+
+ /* wake us again, when the conversions are done */
+ mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(ch2), LRADC_CTRL1);
+ /*
+ * after changing the touchscreen plates setting
+ * the signals need some initial time to settle. Start the
+ * SoC's delay unit and start the conversion later
+ * and automatically.
+ */
+ mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(0) | /* don't trigger ADC */
+ LRADC_DELAY_TRIGGER_DELAYS(1 << 3) | /* trigger DELAY unit#3 */
+ LRADC_DELAY_KICK |
+ LRADC_DELAY_DELAY(lradc->settling_delay), LRADC_DELAY(2));
+}
- /* Check for invalid channel */
- if (chan->channel > LRADC_MAX_TOTAL_CHANS)
- return -EINVAL;
+static unsigned mxs_lradc_read_raw_channel(struct mxs_lradc *lradc,
+ unsigned channel)
+{
+ u32 reg;
+ unsigned num_samples, val;
- /* Validate the channel if it doesn't intersect with reserved chans. */
- bitmap_set(&mask, chan->channel, 1);
- ret = iio_validate_scan_mask_onehot(iio_dev, &mask);
- if (ret)
- return -EINVAL;
+ reg = readl(lradc->base + LRADC_CH(channel));
+ if (reg & LRADC_CH_ACCUMULATE)
+ num_samples = lradc->over_sample_cnt;
+ else
+ num_samples = 1;
+
+ val = (reg & LRADC_CH_VALUE_MASK) >> LRADC_CH_VALUE_OFFSET;
+ return val / num_samples;
+}
+
+static unsigned mxs_lradc_read_ts_pressure(struct mxs_lradc *lradc,
+ unsigned ch1, unsigned ch2)
+{
+ u32 reg, mask;
+ unsigned pressure, m1, m2;
+
+ mask = LRADC_CTRL1_LRADC_IRQ(ch1) | LRADC_CTRL1_LRADC_IRQ(ch2);
+ reg = readl(lradc->base + LRADC_CTRL1) & mask;
+
+ while (reg != mask) {
+ reg = readl(lradc->base + LRADC_CTRL1) & mask;
+ dev_dbg(lradc->dev, "One channel is still busy: %X\n", reg);
+ }
+
+ m1 = mxs_lradc_read_raw_channel(lradc, ch1);
+ m2 = mxs_lradc_read_raw_channel(lradc, ch2);
+
+ if (m2 == 0) {
+ dev_warn(lradc->dev, "Cannot calculate pressure\n");
+ return 1 << (LRADC_RESOLUTION - 1);
+ }
+
+ /* simply scale the value from 0 ... max ADC resolution */
+ pressure = m1;
+ pressure *= (1 << LRADC_RESOLUTION);
+ pressure /= m2;
+
+ dev_dbg(lradc->dev, "Pressure = %u\n", pressure);
+ return pressure;
+}
+
+#define TS_CH_XP 2
+#define TS_CH_YP 3
+#define TS_CH_XM 4
+#define TS_CH_YM 5
+
+static int mxs_lradc_read_ts_channel(struct mxs_lradc *lradc)
+{
+ u32 reg;
+ int val;
+
+ reg = readl(lradc->base + LRADC_CTRL1);
+
+ /* only channels 3 to 5 are of interest here */
+ if (reg & LRADC_CTRL1_LRADC_IRQ(TS_CH_YP)) {
+ mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(TS_CH_YP) |
+ LRADC_CTRL1_LRADC_IRQ(TS_CH_YP), LRADC_CTRL1);
+ val = mxs_lradc_read_raw_channel(lradc, TS_CH_YP);
+ } else if (reg & LRADC_CTRL1_LRADC_IRQ(TS_CH_XM)) {
+ mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(TS_CH_XM) |
+ LRADC_CTRL1_LRADC_IRQ(TS_CH_XM), LRADC_CTRL1);
+ val = mxs_lradc_read_raw_channel(lradc, TS_CH_XM);
+ } else if (reg & LRADC_CTRL1_LRADC_IRQ(TS_CH_YM)) {
+ mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(TS_CH_YM) |
+ LRADC_CTRL1_LRADC_IRQ(TS_CH_YM), LRADC_CTRL1);
+ val = mxs_lradc_read_raw_channel(lradc, TS_CH_YM);
+ } else {
+ return -EIO;
+ }
+
+ mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(2));
+ mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(3));
+
+ return val;
+}
+
+/*
+ * YP(open)--+-------------+
+ * | |--+
+ * | | |
+ * YM(-)--+-------------+ |
+ * +--------------+
+ * | |
+ * XP(weak+) XM(open)
+ *
+ * "weak+" means 200k Ohm VDDIO
+ * (-) means GND
+ */
+static void mxs_lradc_setup_touch_detection(struct mxs_lradc *lradc)
+{
+ /*
+ * In order to detect a touch event the 'touch detect enable' bit
+ * enables:
+ * - a weak pullup to the X+ connector
+ * - a strong ground at the Y- connector
+ */
+ mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
+ mxs_lradc_reg_set(lradc, mxs_lradc_touch_detect_bit(lradc),
+ LRADC_CTRL0);
+}
+
+/*
+ * YP(meas)--+-------------+
+ * | |--+
+ * | | |
+ * YM(open)--+-------------+ |
+ * +--------------+
+ * | |
+ * XP(+) XM(-)
+ *
+ * (+) means here 1.85 V
+ * (-) means here GND
+ */
+static void mxs_lradc_prepare_x_pos(struct mxs_lradc *lradc)
+{
+ mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
+ mxs_lradc_reg_set(lradc, mxs_lradc_drive_x_plate(lradc), LRADC_CTRL0);
+
+ lradc->cur_plate = LRADC_SAMPLE_X;
+ mxs_lradc_setup_ts_channel(lradc, TS_CH_YP);
+}
+
+/*
+ * YP(+)--+-------------+
+ * | |--+
+ * | | |
+ * YM(-)--+-------------+ |
+ * +--------------+
+ * | |
+ * XP(open) XM(meas)
+ *
+ * (+) means here 1.85 V
+ * (-) means here GND
+ */
+static void mxs_lradc_prepare_y_pos(struct mxs_lradc *lradc)
+{
+ mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
+ mxs_lradc_reg_set(lradc, mxs_lradc_drive_y_plate(lradc), LRADC_CTRL0);
+
+ lradc->cur_plate = LRADC_SAMPLE_Y;
+ mxs_lradc_setup_ts_channel(lradc, TS_CH_XM);
+}
+
+/*
+ * YP(+)--+-------------+
+ * | |--+
+ * | | |
+ * YM(meas)--+-------------+ |
+ * +--------------+
+ * | |
+ * XP(meas) XM(-)
+ *
+ * (+) means here 1.85 V
+ * (-) means here GND
+ */
+static void mxs_lradc_prepare_pressure(struct mxs_lradc *lradc)
+{
+ mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
+ mxs_lradc_reg_set(lradc, mxs_lradc_drive_pressure(lradc), LRADC_CTRL0);
+
+ lradc->cur_plate = LRADC_SAMPLE_PRESSURE;
+ mxs_lradc_setup_ts_pressure(lradc, TS_CH_XP, TS_CH_YM);
+}
+
+static void mxs_lradc_enable_touch_detection(struct mxs_lradc *lradc)
+{
+ mxs_lradc_setup_touch_detection(lradc);
+
+ lradc->cur_plate = LRADC_TOUCH;
+ mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ |
+ LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, LRADC_CTRL1);
+ mxs_lradc_reg_set(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, LRADC_CTRL1);
+}
+
+static void mxs_lradc_report_ts_event(struct mxs_lradc *lradc)
+{
+ input_report_abs(lradc->ts_input, ABS_X, lradc->ts_x_pos);
+ input_report_abs(lradc->ts_input, ABS_Y, lradc->ts_y_pos);
+ input_report_abs(lradc->ts_input, ABS_PRESSURE, lradc->ts_pressure);
+ input_report_key(lradc->ts_input, BTN_TOUCH, 1);
+ input_sync(lradc->ts_input);
+}
+
+static void mxs_lradc_complete_touch_event(struct mxs_lradc *lradc)
+{
+ mxs_lradc_setup_touch_detection(lradc);
+ lradc->cur_plate = LRADC_SAMPLE_VALID;
+ /*
+ * start a dummy conversion to burn time to settle the signals
+ * note: we are not interested in the conversion's value
+ */
+ mxs_lradc_reg_wrt(lradc, 0, LRADC_CH(5));
+ mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(5), LRADC_CTRL1);
+ mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(5), LRADC_CTRL1);
+ mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(1 << 5) |
+ LRADC_DELAY_KICK | LRADC_DELAY_DELAY(10), /* waste 5 ms */
+ LRADC_DELAY(2));
+}
+
+/*
+ * in order to avoid false measurements, report only samples where
+ * the surface is still touched after the position measurement
+ */
+static void mxs_lradc_finish_touch_event(struct mxs_lradc *lradc, bool valid)
+{
+ /* if it is still touched, report the sample */
+ if (valid && mxs_lradc_check_touch_event(lradc)) {
+ lradc->ts_valid = true;
+ mxs_lradc_report_ts_event(lradc);
+ }
+
+ /* if it is even still touched, continue with the next measurement */
+ if (mxs_lradc_check_touch_event(lradc)) {
+ mxs_lradc_prepare_y_pos(lradc);
+ return;
+ }
+
+ if (lradc->ts_valid) {
+ /* signal the release */
+ lradc->ts_valid = false;
+ input_report_key(lradc->ts_input, BTN_TOUCH, 0);
+ input_sync(lradc->ts_input);
+ }
+
+ /* if it is released, wait for the next touch via IRQ */
+ lradc->cur_plate = LRADC_TOUCH;
+ mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ, LRADC_CTRL1);
+ mxs_lradc_reg_set(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, LRADC_CTRL1);
+}
+
+/* touchscreen's state machine */
+static void mxs_lradc_handle_touch(struct mxs_lradc *lradc)
+{
+ int val;
+
+ switch (lradc->cur_plate) {
+ case LRADC_TOUCH:
+ /*
+ * start with the Y-pos, because it uses nearly the same plate
+ * settings like the touch detection
+ */
+ if (mxs_lradc_check_touch_event(lradc)) {
+ mxs_lradc_reg_clear(lradc,
+ LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
+ LRADC_CTRL1);
+ mxs_lradc_prepare_y_pos(lradc);
+ }
+ mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ,
+ LRADC_CTRL1);
+ return;
+
+ case LRADC_SAMPLE_Y:
+ val = mxs_lradc_read_ts_channel(lradc);
+ if (val < 0) {
+ mxs_lradc_enable_touch_detection(lradc); /* re-start */
+ return;
+ }
+ lradc->ts_y_pos = val;
+ mxs_lradc_prepare_x_pos(lradc);
+ return;
+
+ case LRADC_SAMPLE_X:
+ val = mxs_lradc_read_ts_channel(lradc);
+ if (val < 0) {
+ mxs_lradc_enable_touch_detection(lradc); /* re-start */
+ return;
+ }
+ lradc->ts_x_pos = val;
+ mxs_lradc_prepare_pressure(lradc);
+ return;
+
+ case LRADC_SAMPLE_PRESSURE:
+ lradc->ts_pressure =
+ mxs_lradc_read_ts_pressure(lradc, TS_CH_XP, TS_CH_YM);
+ mxs_lradc_complete_touch_event(lradc);
+ return;
+
+ case LRADC_SAMPLE_VALID:
+ val = mxs_lradc_read_ts_channel(lradc); /* ignore the value */
+ mxs_lradc_finish_touch_event(lradc, 1);
+ break;
+ }
+}
+
+/*
+ * Raw I/O operations
+ */
+static int mxs_lradc_read_single(struct iio_dev *iio_dev, int chan, int *val)
+{
+ struct mxs_lradc *lradc = iio_priv(iio_dev);
+ int ret;
/*
* See if there is no buffered operation in progess. If there is, simply
@@ -259,28 +834,36 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
if (!ret)
return -EBUSY;
- INIT_COMPLETION(lradc->completion);
+ reinit_completion(&lradc->completion);
/*
* No buffered operation in progress, map the channel and trigger it.
* Virtual channel 0 is always used here as the others are always not
* used if doing raw sampling.
*/
- writel(LRADC_CTRL1_LRADC_IRQ_EN_MASK,
- lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
- writel(0xff, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
+ if (lradc->soc == IMX28_LRADC)
+ mxs_lradc_reg_clear(lradc, LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK,
+ LRADC_CTRL1);
+ mxs_lradc_reg_clear(lradc, 0xff, LRADC_CTRL0);
+
+ /* Enable / disable the divider per requirement */
+ if (test_bit(chan, &lradc->is_divided))
+ mxs_lradc_reg_set(lradc, 1 << LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET,
+ LRADC_CTRL2);
+ else
+ mxs_lradc_reg_clear(lradc,
+ 1 << LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET, LRADC_CTRL2);
/* Clean the slot's previous content, then set new one. */
- writel(LRADC_CTRL4_LRADCSELECT_MASK(0),
- lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_CLR);
- writel(chan->channel, lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_SET);
+ mxs_lradc_reg_clear(lradc, LRADC_CTRL4_LRADCSELECT_MASK(0),
+ LRADC_CTRL4);
+ mxs_lradc_reg_set(lradc, chan, LRADC_CTRL4);
- writel(0, lradc->base + LRADC_CH(0));
+ mxs_lradc_reg_wrt(lradc, 0, LRADC_CH(0));
/* Enable the IRQ and start sampling the channel. */
- writel(LRADC_CTRL1_LRADC_IRQ_EN(0),
- lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET);
- writel(1 << 0, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
+ mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(0), LRADC_CTRL1);
+ mxs_lradc_reg_set(lradc, 1 << 0, LRADC_CTRL0);
/* Wait for completion on the channel, 1 second max. */
ret = wait_for_completion_killable_timeout(&lradc->completion, HZ);
@@ -294,233 +877,230 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
ret = IIO_VAL_INT;
err:
- writel(LRADC_CTRL1_LRADC_IRQ_EN(0),
- lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+ mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(0), LRADC_CTRL1);
mutex_unlock(&lradc->lock);
return ret;
}
-static const struct iio_info mxs_lradc_iio_info = {
- .driver_module = THIS_MODULE,
- .read_raw = mxs_lradc_read_raw,
-};
-
-/*
- * Touchscreen handling
- */
-enum lradc_ts_plate {
- LRADC_SAMPLE_X,
- LRADC_SAMPLE_Y,
- LRADC_SAMPLE_PRESSURE,
-};
-
-static int mxs_lradc_ts_touched(struct mxs_lradc *lradc)
+static int mxs_lradc_read_temp(struct iio_dev *iio_dev, int *val)
{
- uint32_t reg;
+ int ret, min, max;
- /* Enable touch detection. */
- writel(LRADC_CTRL0_PLATE_MASK,
- lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
- writel(LRADC_CTRL0_TOUCH_DETECT_ENABLE,
- lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
+ ret = mxs_lradc_read_single(iio_dev, 8, &min);
+ if (ret != IIO_VAL_INT)
+ return ret;
- msleep(LRADC_TS_SAMPLE_DELAY_MS);
+ ret = mxs_lradc_read_single(iio_dev, 9, &max);
+ if (ret != IIO_VAL_INT)
+ return ret;
- reg = readl(lradc->base + LRADC_STATUS);
+ *val = max - min;
- return reg & LRADC_STATUS_TOUCH_DETECT_RAW;
+ return IIO_VAL_INT;
}
-static int32_t mxs_lradc_ts_sample(struct mxs_lradc *lradc,
- enum lradc_ts_plate plate, int change)
+static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
+ const struct iio_chan_spec *chan,
+ int *val, int *val2, long m)
{
- unsigned long delay, jiff;
- uint32_t reg, ctrl0 = 0, chan = 0;
- /* The touchscreen always uses CTRL4 slot #7. */
- const uint8_t slot = 7;
- uint32_t val;
+ struct mxs_lradc *lradc = iio_priv(iio_dev);
- /*
- * There are three correct configurations of the controller sampling
- * the touchscreen, each of these configuration provides different
- * information from the touchscreen.
- *
- * The following table describes the sampling configurations:
- * +-------------+-------+-------+-------+
- * | Wire \ Axis | X | Y | Z |
- * +---------------------+-------+-------+
- * | X+ (CH2) | HI | TS | TS |
- * +-------------+-------+-------+-------+
- * | X- (CH4) | LO | SH | HI |
- * +-------------+-------+-------+-------+
- * | Y+ (CH3) | SH | HI | HI |
- * +-------------+-------+-------+-------+
- * | Y- (CH5) | TS | LO | SH |
- * +-------------+-------+-------+-------+
- *
- * HI ... strong '1' ; LO ... strong '0'
- * SH ... sample here ; TS ... tri-state
- *
- * There are a few other ways of obtaining the Z coordinate
- * (aka. pressure), but the one in the table seems to be the
- * most reliable one.
- */
- switch (plate) {
- case LRADC_SAMPLE_X:
- ctrl0 = LRADC_CTRL0_XPPSW | LRADC_CTRL0_XNNSW;
- chan = 3;
- break;
- case LRADC_SAMPLE_Y:
- ctrl0 = LRADC_CTRL0_YPPSW | LRADC_CTRL0_YNNSW;
- chan = 4;
- break;
- case LRADC_SAMPLE_PRESSURE:
- ctrl0 = LRADC_CTRL0_YPPSW | LRADC_CTRL0_XNNSW;
- chan = 5;
- break;
- }
+ switch (m) {
+ case IIO_CHAN_INFO_RAW:
+ if (chan->type == IIO_TEMP)
+ return mxs_lradc_read_temp(iio_dev, val);
+
+ return mxs_lradc_read_single(iio_dev, chan->channel, val);
+
+ case IIO_CHAN_INFO_SCALE:
+ if (chan->type == IIO_TEMP) {
+ /* From the datasheet, we have to multiply by 1.012 and
+ * divide by 4
+ */
+ *val = 0;
+ *val2 = 253000;
+ return IIO_VAL_INT_PLUS_MICRO;
+ }
+
+ *val = lradc->vref_mv[chan->channel];
+ *val2 = chan->scan_type.realbits -
+ test_bit(chan->channel, &lradc->is_divided);
+ return IIO_VAL_FRACTIONAL_LOG2;
+
+ case IIO_CHAN_INFO_OFFSET:
+ if (chan->type == IIO_TEMP) {
+ /* The calculated value from the ADC is in Kelvin, we
+ * want Celsius for hwmon so the offset is
+ * -272.15 * scale
+ */
+ *val = -1075;
+ *val2 = 691699;
+
+ return IIO_VAL_INT_PLUS_MICRO;
+ }
- if (change) {
- writel(LRADC_CTRL0_PLATE_MASK,
- lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
- writel(ctrl0, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
+ return -EINVAL;
- writel(LRADC_CTRL4_LRADCSELECT_MASK(slot),
- lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_CLR);
- writel(chan << LRADC_CTRL4_LRADCSELECT_OFFSET(slot),
- lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_SET);
+ default:
+ break;
}
- writel(0xffffffff, lradc->base + LRADC_CH(slot) + STMP_OFFSET_REG_CLR);
- writel(1 << slot, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
+ return -EINVAL;
+}
- delay = jiffies + msecs_to_jiffies(LRADC_TS_SAMPLE_DELAY_MS);
- do {
- jiff = jiffies;
- reg = readl_relaxed(lradc->base + LRADC_CTRL1);
- if (reg & LRADC_CTRL1_LRADC_IRQ(slot))
- break;
- } while (time_before(jiff, delay));
+static int mxs_lradc_write_raw(struct iio_dev *iio_dev,
+ const struct iio_chan_spec *chan,
+ int val, int val2, long m)
+{
+ struct mxs_lradc *lradc = iio_priv(iio_dev);
+ struct mxs_lradc_scale *scale_avail =
+ lradc->scale_avail[chan->channel];
+ int ret;
- writel(LRADC_CTRL1_LRADC_IRQ(slot),
- lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+ ret = mutex_trylock(&lradc->lock);
+ if (!ret)
+ return -EBUSY;
- if (time_after_eq(jiff, delay))
- return -ETIMEDOUT;
+ switch (m) {
+ case IIO_CHAN_INFO_SCALE:
+ ret = -EINVAL;
+ if (val == scale_avail[MXS_LRADC_DIV_DISABLED].integer &&
+ val2 == scale_avail[MXS_LRADC_DIV_DISABLED].nano) {
+ /* divider by two disabled */
+ clear_bit(chan->channel, &lradc->is_divided);
+ ret = 0;
+ } else if (val == scale_avail[MXS_LRADC_DIV_ENABLED].integer &&
+ val2 == scale_avail[MXS_LRADC_DIV_ENABLED].nano) {
+ /* divider by two enabled */
+ set_bit(chan->channel, &lradc->is_divided);
+ ret = 0;
+ }
- val = readl(lradc->base + LRADC_CH(slot));
- val &= LRADC_CH_VALUE_MASK;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
- return val;
+ mutex_unlock(&lradc->lock);
+
+ return ret;
}
-static int32_t mxs_lradc_ts_sample_filter(struct mxs_lradc *lradc,
- enum lradc_ts_plate plate)
+static int mxs_lradc_write_raw_get_fmt(struct iio_dev *iio_dev,
+ const struct iio_chan_spec *chan,
+ long m)
{
- int32_t val, tot = 0;
- int i;
+ return IIO_VAL_INT_PLUS_NANO;
+}
- val = mxs_lradc_ts_sample(lradc, plate, 1);
+static ssize_t mxs_lradc_show_scale_available_ch(struct device *dev,
+ struct device_attribute *attr,
+ char *buf,
+ int ch)
+{
+ struct iio_dev *iio = dev_to_iio_dev(dev);
+ struct mxs_lradc *lradc = iio_priv(iio);
+ int i, len = 0;
- /* Delay a bit so the touchscreen is stable. */
- mdelay(2);
+ for (i = 0; i < ARRAY_SIZE(lradc->scale_avail[ch]); i++)
+ len += sprintf(buf + len, "%d.%09u ",
+ lradc->scale_avail[ch][i].integer,
+ lradc->scale_avail[ch][i].nano);
- for (i = 0; i < LRADC_TS_SAMPLE_AMOUNT; i++) {
- val = mxs_lradc_ts_sample(lradc, plate, 0);
- tot += val;
- }
+ len += sprintf(buf + len, "\n");
- return tot / LRADC_TS_SAMPLE_AMOUNT;
+ return len;
}
-static void mxs_lradc_ts_work(struct work_struct *ts_work)
+static ssize_t mxs_lradc_show_scale_available(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
{
- struct mxs_lradc *lradc = container_of(ts_work,
- struct mxs_lradc, ts_work);
- int val_x, val_y, val_p;
- bool valid = false;
-
- while (mxs_lradc_ts_touched(lradc)) {
- /* Disable touch detector so we can sample the touchscreen. */
- writel(LRADC_CTRL0_TOUCH_DETECT_ENABLE,
- lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
-
- if (likely(valid)) {
- input_report_abs(lradc->ts_input, ABS_X, val_x);
- input_report_abs(lradc->ts_input, ABS_Y, val_y);
- input_report_abs(lradc->ts_input, ABS_PRESSURE, val_p);
- input_report_key(lradc->ts_input, BTN_TOUCH, 1);
- input_sync(lradc->ts_input);
- }
-
- valid = false;
-
- val_x = mxs_lradc_ts_sample_filter(lradc, LRADC_SAMPLE_X);
- if (val_x < 0)
- continue;
- val_y = mxs_lradc_ts_sample_filter(lradc, LRADC_SAMPLE_Y);
- if (val_y < 0)
- continue;
- val_p = mxs_lradc_ts_sample_filter(lradc, LRADC_SAMPLE_PRESSURE);
- if (val_p < 0)
- continue;
+ struct iio_dev_attr *iio_attr = to_iio_dev_attr(attr);
- valid = true;
- }
+ return mxs_lradc_show_scale_available_ch(dev, attr, buf,
+ iio_attr->address);
+}
- input_report_abs(lradc->ts_input, ABS_PRESSURE, 0);
- input_report_key(lradc->ts_input, BTN_TOUCH, 0);
- input_sync(lradc->ts_input);
+#define SHOW_SCALE_AVAILABLE_ATTR(ch) \
+static IIO_DEVICE_ATTR(in_voltage##ch##_scale_available, S_IRUGO, \
+ mxs_lradc_show_scale_available, NULL, ch)
+
+SHOW_SCALE_AVAILABLE_ATTR(0);
+SHOW_SCALE_AVAILABLE_ATTR(1);
+SHOW_SCALE_AVAILABLE_ATTR(2);
+SHOW_SCALE_AVAILABLE_ATTR(3);
+SHOW_SCALE_AVAILABLE_ATTR(4);
+SHOW_SCALE_AVAILABLE_ATTR(5);
+SHOW_SCALE_AVAILABLE_ATTR(6);
+SHOW_SCALE_AVAILABLE_ATTR(7);
+SHOW_SCALE_AVAILABLE_ATTR(10);
+SHOW_SCALE_AVAILABLE_ATTR(11);
+SHOW_SCALE_AVAILABLE_ATTR(12);
+SHOW_SCALE_AVAILABLE_ATTR(13);
+SHOW_SCALE_AVAILABLE_ATTR(14);
+SHOW_SCALE_AVAILABLE_ATTR(15);
+
+static struct attribute *mxs_lradc_attributes[] = {
+ &iio_dev_attr_in_voltage0_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage1_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage2_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage3_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage4_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage5_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage6_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage7_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage10_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage11_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage12_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage13_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage14_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage15_scale_available.dev_attr.attr,
+ NULL
+};
- /* Do not restart the TS IRQ if the driver is shutting down. */
- if (lradc->stop_touchscreen)
- return;
+static const struct attribute_group mxs_lradc_attribute_group = {
+ .attrs = mxs_lradc_attributes,
+};
- /* Restart the touchscreen interrupts. */
- writel(LRADC_CTRL1_TOUCH_DETECT_IRQ,
- lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
- writel(LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
- lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET);
-}
+static const struct iio_info mxs_lradc_iio_info = {
+ .driver_module = THIS_MODULE,
+ .read_raw = mxs_lradc_read_raw,
+ .write_raw = mxs_lradc_write_raw,
+ .write_raw_get_fmt = mxs_lradc_write_raw_get_fmt,
+ .attrs = &mxs_lradc_attribute_group,
+};
static int mxs_lradc_ts_open(struct input_dev *dev)
{
struct mxs_lradc *lradc = input_get_drvdata(dev);
- /* The touchscreen is starting. */
- lradc->stop_touchscreen = false;
-
/* Enable the touch-detect circuitry. */
- writel(LRADC_CTRL0_TOUCH_DETECT_ENABLE,
- lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
-
- /* Enable the touch-detect IRQ. */
- writel(LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
- lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET);
+ mxs_lradc_enable_touch_detection(lradc);
return 0;
}
-static void mxs_lradc_ts_close(struct input_dev *dev)
+static void mxs_lradc_disable_ts(struct mxs_lradc *lradc)
{
- struct mxs_lradc *lradc = input_get_drvdata(dev);
-
- /* Indicate the touchscreen is stopping. */
- lradc->stop_touchscreen = true;
- mb();
+ /* stop all interrupts from firing */
+ mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN |
+ LRADC_CTRL1_LRADC_IRQ_EN(2) | LRADC_CTRL1_LRADC_IRQ_EN(3) |
+ LRADC_CTRL1_LRADC_IRQ_EN(4) | LRADC_CTRL1_LRADC_IRQ_EN(5),
+ LRADC_CTRL1);
- /* Wait until touchscreen thread finishes any possible remnants. */
- cancel_work_sync(&lradc->ts_work);
+ /* Power-down touchscreen touch-detect circuitry. */
+ mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
+}
- /* Disable touchscreen touch-detect IRQ. */
- writel(LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
- lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+static void mxs_lradc_ts_close(struct input_dev *dev)
+{
+ struct mxs_lradc *lradc = input_get_drvdata(dev);
- /* Power-down touchscreen touch-detect circuitry. */
- writel(LRADC_CTRL0_TOUCH_DETECT_ENABLE,
- lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
+ mxs_lradc_disable_ts(lradc);
}
static int mxs_lradc_ts_register(struct mxs_lradc *lradc)
@@ -533,10 +1113,8 @@ static int mxs_lradc_ts_register(struct mxs_lradc *lradc)
return 0;
input = input_allocate_device();
- if (!input) {
- dev_err(dev, "Failed to allocate TS device!\n");
+ if (!input)
return -ENOMEM;
- }
input->name = DRIVER_NAME;
input->id.bustype = BUS_HOST;
@@ -547,9 +1125,10 @@ static int mxs_lradc_ts_register(struct mxs_lradc *lradc)
__set_bit(EV_ABS, input->evbit);
__set_bit(EV_KEY, input->evbit);
__set_bit(BTN_TOUCH, input->keybit);
- input_set_abs_params(input, ABS_X, 0, LRADC_CH_VALUE_MASK, 0, 0);
- input_set_abs_params(input, ABS_Y, 0, LRADC_CH_VALUE_MASK, 0, 0);
- input_set_abs_params(input, ABS_PRESSURE, 0, LRADC_CH_VALUE_MASK, 0, 0);
+ input_set_abs_params(input, ABS_X, 0, LRADC_SINGLE_SAMPLE_MASK, 0, 0);
+ input_set_abs_params(input, ABS_Y, 0, LRADC_SINGLE_SAMPLE_MASK, 0, 0);
+ input_set_abs_params(input, ABS_PRESSURE, 0, LRADC_SINGLE_SAMPLE_MASK,
+ 0, 0);
lradc->ts_input = input;
input_set_drvdata(input, lradc);
@@ -565,8 +1144,7 @@ static void mxs_lradc_ts_unregister(struct mxs_lradc *lradc)
if (!lradc->use_touchscreen)
return;
- cancel_work_sync(&lradc->ts_work);
-
+ mxs_lradc_disable_ts(lradc);
input_unregister_device(lradc->ts_input);
}
@@ -579,31 +1157,25 @@ static irqreturn_t mxs_lradc_handle_irq(int irq, void *data)
struct mxs_lradc *lradc = iio_priv(iio);
unsigned long reg = readl(lradc->base + LRADC_CTRL1);
const uint32_t ts_irq_mask =
- LRADC_CTRL1_TOUCH_DETECT_IRQ_EN |
- LRADC_CTRL1_TOUCH_DETECT_IRQ;
+ LRADC_CTRL1_TOUCH_DETECT_IRQ |
+ LRADC_CTRL1_LRADC_IRQ(2) |
+ LRADC_CTRL1_LRADC_IRQ(3) |
+ LRADC_CTRL1_LRADC_IRQ(4) |
+ LRADC_CTRL1_LRADC_IRQ(5);
- if (!(reg & LRADC_CTRL1_LRADC_IRQ_MASK))
+ if (!(reg & mxs_lradc_irq_mask(lradc)))
return IRQ_NONE;
- /*
- * Touchscreen IRQ handling code has priority and therefore
- * is placed here. In case touchscreen IRQ arrives, disable
- * it ASAP
- */
- if (reg & LRADC_CTRL1_TOUCH_DETECT_IRQ) {
- writel(ts_irq_mask,
- lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
- if (!lradc->stop_touchscreen)
- schedule_work(&lradc->ts_work);
- }
+ if (lradc->use_touchscreen && (reg & ts_irq_mask))
+ mxs_lradc_handle_touch(lradc);
if (iio_buffer_enabled(iio))
iio_trigger_poll(iio->trig, iio_get_time_ns());
else if (reg & LRADC_CTRL1_LRADC_IRQ(0))
complete(&lradc->completion);
- writel(reg & LRADC_CTRL1_LRADC_IRQ_MASK,
- lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+ mxs_lradc_reg_clear(lradc, reg & mxs_lradc_irq_mask(lradc),
+ LRADC_CTRL1);
return IRQ_HANDLED;
}
@@ -622,19 +1194,13 @@ static irqreturn_t mxs_lradc_trigger_handler(int irq, void *p)
for_each_set_bit(i, iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS) {
lradc->buffer[j] = readl(lradc->base + LRADC_CH(j));
- writel(chan_value, lradc->base + LRADC_CH(j));
+ mxs_lradc_reg_wrt(lradc, chan_value, LRADC_CH(j));
lradc->buffer[j] &= LRADC_CH_VALUE_MASK;
lradc->buffer[j] /= LRADC_DELAY_TIMER_LOOP;
j++;
}
- if (iio->scan_timestamp) {
- s64 *timestamp = (s64 *)((u8 *)lradc->buffer +
- ALIGN(j, sizeof(s64)));
- *timestamp = pf->timestamp;
- }
-
- iio_push_to_buffers(iio, (u8 *)lradc->buffer);
+ iio_push_to_buffers_with_timestamp(iio, lradc->buffer, pf->timestamp);
iio_trigger_notify_done(iio->trig);
@@ -647,7 +1213,7 @@ static int mxs_lradc_configure_trigger(struct iio_trigger *trig, bool state)
struct mxs_lradc *lradc = iio_priv(iio);
const uint32_t st = state ? STMP_OFFSET_REG_SET : STMP_OFFSET_REG_CLR;
- writel(LRADC_DELAY_KICK, lradc->base + LRADC_DELAY(0) + st);
+ mxs_lradc_reg_wrt(lradc, LRADC_DELAY_KICK, LRADC_DELAY(0) + st);
return 0;
}
@@ -661,12 +1227,13 @@ static int mxs_lradc_trigger_init(struct iio_dev *iio)
{
int ret;
struct iio_trigger *trig;
+ struct mxs_lradc *lradc = iio_priv(iio);
trig = iio_trigger_alloc("%s-dev%i", iio->name, iio->id);
if (trig == NULL)
return -ENOMEM;
- trig->dev.parent = iio->dev.parent;
+ trig->dev.parent = lradc->dev;
iio_trigger_set_drvdata(trig, iio);
trig->ops = &mxs_lradc_trigger_ops;
@@ -676,15 +1243,17 @@ static int mxs_lradc_trigger_init(struct iio_dev *iio)
return ret;
}
- iio->trig = trig;
+ lradc->trig = trig;
return 0;
}
static void mxs_lradc_trigger_remove(struct iio_dev *iio)
{
- iio_trigger_unregister(iio->trig);
- iio_trigger_free(iio->trig);
+ struct mxs_lradc *lradc = iio_priv(iio);
+
+ iio_trigger_unregister(lradc->trig);
+ iio_trigger_free(lradc->trig);
}
static int mxs_lradc_buffer_preenable(struct iio_dev *iio)
@@ -697,7 +1266,8 @@ static int mxs_lradc_buffer_preenable(struct iio_dev *iio)
uint32_t ctrl1_irq = 0;
const uint32_t chan_value = LRADC_CH_ACCUMULATE |
((LRADC_DELAY_TIMER_LOOP - 1) << LRADC_CH_NUM_SAMPLES_OFFSET);
- const int len = bitmap_weight(iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS);
+ const int len = bitmap_weight(iio->active_scan_mask,
+ LRADC_MAX_TOTAL_CHANS);
if (!len)
return -EINVAL;
@@ -716,38 +1286,30 @@ static int mxs_lradc_buffer_preenable(struct iio_dev *iio)
goto err_mem;
}
- ret = iio_sw_buffer_preenable(iio);
- if (ret < 0)
- goto err_buf;
-
- writel(LRADC_CTRL1_LRADC_IRQ_EN_MASK,
- lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
- writel(0xff, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
+ if (lradc->soc == IMX28_LRADC)
+ mxs_lradc_reg_clear(lradc, LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK,
+ LRADC_CTRL1);
+ mxs_lradc_reg_clear(lradc, 0xff, LRADC_CTRL0);
for_each_set_bit(chan, iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS) {
ctrl4_set |= chan << LRADC_CTRL4_LRADCSELECT_OFFSET(ofs);
ctrl4_clr |= LRADC_CTRL4_LRADCSELECT_MASK(ofs);
ctrl1_irq |= LRADC_CTRL1_LRADC_IRQ_EN(ofs);
- writel(chan_value, lradc->base + LRADC_CH(ofs));
+ mxs_lradc_reg_wrt(lradc, chan_value, LRADC_CH(ofs));
bitmap_set(&enable, ofs, 1);
ofs++;
}
- writel(LRADC_DELAY_TRIGGER_LRADCS_MASK | LRADC_DELAY_KICK,
- lradc->base + LRADC_DELAY(0) + STMP_OFFSET_REG_CLR);
-
- writel(ctrl4_clr, lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_CLR);
- writel(ctrl4_set, lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_SET);
-
- writel(ctrl1_irq, lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET);
-
- writel(enable << LRADC_DELAY_TRIGGER_LRADCS_OFFSET,
- lradc->base + LRADC_DELAY(0) + STMP_OFFSET_REG_SET);
+ mxs_lradc_reg_clear(lradc, LRADC_DELAY_TRIGGER_LRADCS_MASK |
+ LRADC_DELAY_KICK, LRADC_DELAY(0));
+ mxs_lradc_reg_clear(lradc, ctrl4_clr, LRADC_CTRL4);
+ mxs_lradc_reg_set(lradc, ctrl4_set, LRADC_CTRL4);
+ mxs_lradc_reg_set(lradc, ctrl1_irq, LRADC_CTRL1);
+ mxs_lradc_reg_set(lradc, enable << LRADC_DELAY_TRIGGER_LRADCS_OFFSET,
+ LRADC_DELAY(0));
return 0;
-err_buf:
- kfree(lradc->buffer);
err_mem:
mutex_unlock(&lradc->lock);
return ret;
@@ -757,12 +1319,13 @@ static int mxs_lradc_buffer_postdisable(struct iio_dev *iio)
{
struct mxs_lradc *lradc = iio_priv(iio);
- writel(LRADC_DELAY_TRIGGER_LRADCS_MASK | LRADC_DELAY_KICK,
- lradc->base + LRADC_DELAY(0) + STMP_OFFSET_REG_CLR);
+ mxs_lradc_reg_clear(lradc, LRADC_DELAY_TRIGGER_LRADCS_MASK |
+ LRADC_DELAY_KICK, LRADC_DELAY(0));
- writel(0xff, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
- writel(LRADC_CTRL1_LRADC_IRQ_EN_MASK,
- lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+ mxs_lradc_reg_clear(lradc, 0xff, LRADC_CTRL0);
+ if (lradc->soc == IMX28_LRADC)
+ mxs_lradc_reg_clear(lradc, LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK,
+ LRADC_CTRL1);
kfree(lradc->buffer);
mutex_unlock(&lradc->lock);
@@ -817,11 +1380,13 @@ static const struct iio_buffer_setup_ops mxs_lradc_buffer_ops = {
.type = (chan_type), \
.indexed = 1, \
.scan_index = (idx), \
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE), \
.channel = (idx), \
+ .address = (idx), \
.scan_type = { \
.sign = 'u', \
- .realbits = 18, \
+ .realbits = LRADC_RESOLUTION, \
.storagebits = 32, \
}, \
}
@@ -835,8 +1400,17 @@ static const struct iio_chan_spec mxs_lradc_chan_spec[] = {
MXS_ADC_CHAN(5, IIO_VOLTAGE),
MXS_ADC_CHAN(6, IIO_VOLTAGE),
MXS_ADC_CHAN(7, IIO_VOLTAGE), /* VBATT */
- MXS_ADC_CHAN(8, IIO_TEMP), /* Temp sense 0 */
- MXS_ADC_CHAN(9, IIO_TEMP), /* Temp sense 1 */
+ /* Combined Temperature sensors */
+ {
+ .type = IIO_TEMP,
+ .indexed = 1,
+ .scan_index = 8,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_OFFSET) |
+ BIT(IIO_CHAN_INFO_SCALE),
+ .channel = 8,
+ .scan_type = {.sign = 'u', .realbits = 18, .storagebits = 32,},
+ },
MXS_ADC_CHAN(10, IIO_VOLTAGE), /* VDDIO */
MXS_ADC_CHAN(11, IIO_VOLTAGE), /* VTH */
MXS_ADC_CHAN(12, IIO_VOLTAGE), /* VDDA */
@@ -845,45 +1419,49 @@ static const struct iio_chan_spec mxs_lradc_chan_spec[] = {
MXS_ADC_CHAN(15, IIO_VOLTAGE), /* VDD5V */
};
-static void mxs_lradc_hw_init(struct mxs_lradc *lradc)
+static int mxs_lradc_hw_init(struct mxs_lradc *lradc)
{
/* The ADC always uses DELAY CHANNEL 0. */
const uint32_t adc_cfg =
(1 << (LRADC_DELAY_TRIGGER_DELAYS_OFFSET + 0)) |
(LRADC_DELAY_TIMER_PER << LRADC_DELAY_DELAY_OFFSET);
- stmp_reset_block(lradc->base);
+ int ret = stmp_reset_block(lradc->base);
+ if (ret)
+ return ret;
/* Configure DELAY CHANNEL 0 for generic ADC sampling. */
- writel(adc_cfg, lradc->base + LRADC_DELAY(0));
+ mxs_lradc_reg_wrt(lradc, adc_cfg, LRADC_DELAY(0));
/* Disable remaining DELAY CHANNELs */
- writel(0, lradc->base + LRADC_DELAY(1));
- writel(0, lradc->base + LRADC_DELAY(2));
- writel(0, lradc->base + LRADC_DELAY(3));
+ mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(1));
+ mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(2));
+ mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(3));
/* Configure the touchscreen type */
- writel(LRADC_CTRL0_TOUCH_SCREEN_TYPE,
- lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
+ if (lradc->soc == IMX28_LRADC) {
+ mxs_lradc_reg_clear(lradc, LRADC_CTRL0_MX28_TOUCH_SCREEN_TYPE,
+ LRADC_CTRL0);
- if (lradc->use_touchscreen == MXS_LRADC_TOUCHSCREEN_5WIRE) {
- writel(LRADC_CTRL0_TOUCH_SCREEN_TYPE,
- lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
+ if (lradc->use_touchscreen == MXS_LRADC_TOUCHSCREEN_5WIRE)
+ mxs_lradc_reg_set(lradc, LRADC_CTRL0_MX28_TOUCH_SCREEN_TYPE,
+ LRADC_CTRL0);
}
/* Start internal temperature sensing. */
- writel(0, lradc->base + LRADC_CTRL2);
+ mxs_lradc_reg_wrt(lradc, 0, LRADC_CTRL2);
+
+ return 0;
}
static void mxs_lradc_hw_stop(struct mxs_lradc *lradc)
{
int i;
- writel(LRADC_CTRL1_LRADC_IRQ_EN_MASK,
- lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+ mxs_lradc_reg_clear(lradc, mxs_lradc_irq_en_mask(lradc), LRADC_CTRL1);
for (i = 0; i < LRADC_MAX_DELAY_CHANS; i++)
- writel(0, lradc->base + LRADC_DELAY(i));
+ mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(i));
}
static const struct of_device_id mxs_lradc_dt_ids[] = {
@@ -893,6 +1471,52 @@ static const struct of_device_id mxs_lradc_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, mxs_lradc_dt_ids);
+static int mxs_lradc_probe_touchscreen(struct mxs_lradc *lradc,
+ struct device_node *lradc_node)
+{
+ int ret;
+ u32 ts_wires = 0, adapt;
+
+ ret = of_property_read_u32(lradc_node, "fsl,lradc-touchscreen-wires",
+ &ts_wires);
+ if (ret)
+ return -ENODEV; /* touchscreen feature disabled */
+
+ switch (ts_wires) {
+ case 4:
+ lradc->use_touchscreen = MXS_LRADC_TOUCHSCREEN_4WIRE;
+ break;
+ case 5:
+ if (lradc->soc == IMX28_LRADC) {
+ lradc->use_touchscreen = MXS_LRADC_TOUCHSCREEN_5WIRE;
+ break;
+ }
+ /* fall through an error message for i.MX23 */
+ default:
+ dev_err(lradc->dev,
+ "Unsupported number of touchscreen wires (%d)\n",
+ ts_wires);
+ return -EINVAL;
+ }
+
+ lradc->over_sample_cnt = 4;
+ ret = of_property_read_u32(lradc_node, "fsl,ave-ctrl", &adapt);
+ if (ret == 0)
+ lradc->over_sample_cnt = adapt;
+
+ lradc->over_sample_delay = 2;
+ ret = of_property_read_u32(lradc_node, "fsl,ave-delay", &adapt);
+ if (ret == 0)
+ lradc->over_sample_delay = adapt;
+
+ lradc->settling_delay = 10;
+ ret = of_property_read_u32(lradc_node, "fsl,settling", &adapt);
+ if (ret == 0)
+ lradc->settling_delay = adapt;
+
+ return 0;
+}
+
static int mxs_lradc_probe(struct platform_device *pdev)
{
const struct of_device_id *of_id =
@@ -904,58 +1528,55 @@ static int mxs_lradc_probe(struct platform_device *pdev)
struct mxs_lradc *lradc;
struct iio_dev *iio;
struct resource *iores;
- uint32_t ts_wires = 0;
- int ret = 0;
- int i;
+ int ret = 0, touch_ret;
+ int i, s;
+ uint64_t scale_uv;
/* Allocate the IIO device. */
- iio = iio_device_alloc(sizeof(*lradc));
+ iio = devm_iio_device_alloc(dev, sizeof(*lradc));
if (!iio) {
dev_err(dev, "Failed to allocate IIO device\n");
return -ENOMEM;
}
lradc = iio_priv(iio);
+ lradc->soc = (enum mxs_lradc_id)of_id->data;
/* Grab the memory area */
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
lradc->dev = &pdev->dev;
lradc->base = devm_ioremap_resource(dev, iores);
- if (IS_ERR(lradc->base)) {
- ret = PTR_ERR(lradc->base);
- goto err_addr;
+ if (IS_ERR(lradc->base))
+ return PTR_ERR(lradc->base);
+
+ lradc->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(lradc->clk)) {
+ dev_err(dev, "Failed to get the delay unit clock\n");
+ return PTR_ERR(lradc->clk);
+ }
+ ret = clk_prepare_enable(lradc->clk);
+ if (ret != 0) {
+ dev_err(dev, "Failed to enable the delay unit clock\n");
+ return ret;
}
- INIT_WORK(&lradc->ts_work, mxs_lradc_ts_work);
-
- /* Check if touchscreen is enabled in DT. */
- ret = of_property_read_u32(node, "fsl,lradc-touchscreen-wires",
- &ts_wires);
- if (ret)
- dev_info(dev, "Touchscreen not enabled.\n");
- else if (ts_wires == 4)
- lradc->use_touchscreen = MXS_LRADC_TOUCHSCREEN_4WIRE;
- else if (ts_wires == 5)
- lradc->use_touchscreen = MXS_LRADC_TOUCHSCREEN_5WIRE;
- else
- dev_warn(dev, "Unsupported number of touchscreen wires (%d)\n",
- ts_wires);
+ touch_ret = mxs_lradc_probe_touchscreen(lradc, node);
/* Grab all IRQ sources */
for (i = 0; i < of_cfg->irq_count; i++) {
lradc->irq[i] = platform_get_irq(pdev, i);
- if (lradc->irq[i] < 0) {
- ret = -EINVAL;
- goto err_addr;
- }
+ if (lradc->irq[i] < 0)
+ return lradc->irq[i];
ret = devm_request_irq(dev, lradc->irq[i],
mxs_lradc_handle_irq, 0,
of_cfg->irq_name[i], iio);
if (ret)
- goto err_addr;
+ return ret;
}
+ lradc->vref_mv = of_cfg->vref_mv;
+
platform_set_drvdata(pdev, iio);
init_completion(&lradc->completion);
@@ -973,20 +1594,44 @@ static int mxs_lradc_probe(struct platform_device *pdev)
&mxs_lradc_trigger_handler,
&mxs_lradc_buffer_ops);
if (ret)
- goto err_addr;
+ return ret;
ret = mxs_lradc_trigger_init(iio);
if (ret)
goto err_trig;
- /* Configure the hardware. */
- mxs_lradc_hw_init(lradc);
+ /* Populate available ADC input ranges */
+ for (i = 0; i < LRADC_MAX_TOTAL_CHANS; i++) {
+ for (s = 0; s < ARRAY_SIZE(lradc->scale_avail[i]); s++) {
+ /*
+ * [s=0] = optional divider by two disabled (default)
+ * [s=1] = optional divider by two enabled
+ *
+ * The scale is calculated by doing:
+ * Vref >> (realbits - s)
+ * which multiplies by two on the second component
+ * of the array.
+ */
+ scale_uv = ((u64)lradc->vref_mv[i] * 100000000) >>
+ (LRADC_RESOLUTION - s);
+ lradc->scale_avail[i][s].nano =
+ do_div(scale_uv, 100000000) * 10;
+ lradc->scale_avail[i][s].integer = scale_uv;
+ }
+ }
- /* Register the touchscreen input device. */
- ret = mxs_lradc_ts_register(lradc);
+ /* Configure the hardware. */
+ ret = mxs_lradc_hw_init(lradc);
if (ret)
goto err_dev;
+ /* Register the touchscreen input device. */
+ if (touch_ret == 0) {
+ ret = mxs_lradc_ts_register(lradc);
+ if (ret)
+ goto err_ts_register;
+ }
+
/* Register IIO device. */
ret = iio_device_register(iio);
if (ret) {
@@ -998,12 +1643,12 @@ static int mxs_lradc_probe(struct platform_device *pdev)
err_ts:
mxs_lradc_ts_unregister(lradc);
+err_ts_register:
+ mxs_lradc_hw_stop(lradc);
err_dev:
mxs_lradc_trigger_remove(iio);
err_trig:
iio_triggered_buffer_cleanup(iio);
-err_addr:
- iio_device_free(iio);
return ret;
}
@@ -1012,15 +1657,13 @@ static int mxs_lradc_remove(struct platform_device *pdev)
struct iio_dev *iio = platform_get_drvdata(pdev);
struct mxs_lradc *lradc = iio_priv(iio);
+ iio_device_unregister(iio);
mxs_lradc_ts_unregister(lradc);
-
mxs_lradc_hw_stop(lradc);
-
- iio_device_unregister(iio);
- iio_triggered_buffer_cleanup(iio);
mxs_lradc_trigger_remove(iio);
- iio_device_free(iio);
+ iio_triggered_buffer_cleanup(iio);
+ clk_disable_unprepare(lradc->clk);
return 0;
}
@@ -1039,3 +1682,4 @@ module_platform_driver(mxs_lradc_driver);
MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
MODULE_DESCRIPTION("Freescale i.MX28 LRADC driver");
MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/staging/iio/adc/spear_adc.c b/drivers/staging/iio/adc/spear_adc.c
index 736219c3030..c5492ba5075 100644
--- a/drivers/staging/iio/adc/spear_adc.c
+++ b/drivers/staging/iio/adc/spear_adc.c
@@ -22,39 +22,36 @@
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
-/*
- * SPEAR registers definitions
- */
-
-#define SCAN_RATE_LO(x) ((x) & 0xFFFF)
-#define SCAN_RATE_HI(x) (((x) >> 0x10) & 0xFFFF)
-#define CLK_LOW(x) (((x) & 0xf) << 0)
-#define CLK_HIGH(x) (((x) & 0xf) << 4)
+/* SPEAR registers definitions */
+#define SPEAR600_ADC_SCAN_RATE_LO(x) ((x) & 0xFFFF)
+#define SPEAR600_ADC_SCAN_RATE_HI(x) (((x) >> 0x10) & 0xFFFF)
+#define SPEAR_ADC_CLK_LOW(x) (((x) & 0xf) << 0)
+#define SPEAR_ADC_CLK_HIGH(x) (((x) & 0xf) << 4)
/* Bit definitions for SPEAR_ADC_STATUS */
-#define START_CONVERSION (1 << 0)
-#define CHANNEL_NUM(x) ((x) << 1)
-#define ADC_ENABLE (1 << 4)
-#define AVG_SAMPLE(x) ((x) << 5)
-#define VREF_INTERNAL (1 << 9)
+#define SPEAR_ADC_STATUS_START_CONVERSION (1 << 0)
+#define SPEAR_ADC_STATUS_CHANNEL_NUM(x) ((x) << 1)
+#define SPEAR_ADC_STATUS_ADC_ENABLE (1 << 4)
+#define SPEAR_ADC_STATUS_AVG_SAMPLE(x) ((x) << 5)
+#define SPEAR_ADC_STATUS_VREF_INTERNAL (1 << 9)
-#define DATA_MASK 0x03ff
-#define DATA_BITS 10
+#define SPEAR_ADC_DATA_MASK 0x03ff
+#define SPEAR_ADC_DATA_BITS 10
-#define MOD_NAME "spear-adc"
+#define SPEAR_ADC_MOD_NAME "spear-adc"
-#define ADC_CHANNEL_NUM 8
+#define SPEAR_ADC_CHANNEL_NUM 8
-#define CLK_MIN 2500000
-#define CLK_MAX 20000000
+#define SPEAR_ADC_CLK_MIN 2500000
+#define SPEAR_ADC_CLK_MAX 20000000
struct adc_regs_spear3xx {
u32 status;
u32 average;
u32 scan_rate;
u32 clk; /* Not avail for 1340 & 1310 */
- u32 ch_ctrl[ADC_CHANNEL_NUM];
- u32 ch_data[ADC_CHANNEL_NUM];
+ u32 ch_ctrl[SPEAR_ADC_CHANNEL_NUM];
+ u32 ch_data[SPEAR_ADC_CHANNEL_NUM];
};
struct chan_data {
@@ -66,14 +63,14 @@ struct adc_regs_spear6xx {
u32 status;
u32 pad[2];
u32 clk;
- u32 ch_ctrl[ADC_CHANNEL_NUM];
- struct chan_data ch_data[ADC_CHANNEL_NUM];
+ u32 ch_ctrl[SPEAR_ADC_CHANNEL_NUM];
+ struct chan_data ch_data[SPEAR_ADC_CHANNEL_NUM];
u32 scan_rate_lo;
u32 scan_rate_hi;
struct chan_data average;
};
-struct spear_adc_info {
+struct spear_adc_state {
struct device_node *np;
struct adc_regs_spear3xx __iomem *adc_base_spear3xx;
struct adc_regs_spear6xx __iomem *adc_base_spear6xx;
@@ -91,102 +88,129 @@ struct spear_adc_info {
* static inline functions, because of different register offsets
* on different SoC variants (SPEAr300 vs SPEAr600 etc).
*/
-static void spear_adc_set_status(struct spear_adc_info *info, u32 val)
+static void spear_adc_set_status(struct spear_adc_state *st, u32 val)
{
- __raw_writel(val, &info->adc_base_spear6xx->status);
+ __raw_writel(val, &st->adc_base_spear6xx->status);
}
-static void spear_adc_set_clk(struct spear_adc_info *info, u32 val)
+static void spear_adc_set_clk(struct spear_adc_state *st, u32 val)
{
u32 clk_high, clk_low, count;
- u32 apb_clk = clk_get_rate(info->clk);
+ u32 apb_clk = clk_get_rate(st->clk);
count = (apb_clk + val - 1) / val;
clk_low = count / 2;
clk_high = count - clk_low;
- info->current_clk = apb_clk / count;
+ st->current_clk = apb_clk / count;
- __raw_writel(CLK_LOW(clk_low) | CLK_HIGH(clk_high),
- &info->adc_base_spear6xx->clk);
+ __raw_writel(SPEAR_ADC_CLK_LOW(clk_low) | SPEAR_ADC_CLK_HIGH(clk_high),
+ &st->adc_base_spear6xx->clk);
}
-static void spear_adc_set_ctrl(struct spear_adc_info *info, int n,
+static void spear_adc_set_ctrl(struct spear_adc_state *st, int n,
u32 val)
{
- __raw_writel(val, &info->adc_base_spear6xx->ch_ctrl[n]);
+ __raw_writel(val, &st->adc_base_spear6xx->ch_ctrl[n]);
}
-static u32 spear_adc_get_average(struct spear_adc_info *info)
+static u32 spear_adc_get_average(struct spear_adc_state *st)
{
- if (of_device_is_compatible(info->np, "st,spear600-adc")) {
- return __raw_readl(&info->adc_base_spear6xx->average.msb) &
- DATA_MASK;
+ if (of_device_is_compatible(st->np, "st,spear600-adc")) {
+ return __raw_readl(&st->adc_base_spear6xx->average.msb) &
+ SPEAR_ADC_DATA_MASK;
} else {
- return __raw_readl(&info->adc_base_spear3xx->average) &
- DATA_MASK;
+ return __raw_readl(&st->adc_base_spear3xx->average) &
+ SPEAR_ADC_DATA_MASK;
}
}
-static void spear_adc_set_scanrate(struct spear_adc_info *info, u32 rate)
+static void spear_adc_set_scanrate(struct spear_adc_state *st, u32 rate)
{
- if (of_device_is_compatible(info->np, "st,spear600-adc")) {
- __raw_writel(SCAN_RATE_LO(rate),
- &info->adc_base_spear6xx->scan_rate_lo);
- __raw_writel(SCAN_RATE_HI(rate),
- &info->adc_base_spear6xx->scan_rate_hi);
+ if (of_device_is_compatible(st->np, "st,spear600-adc")) {
+ __raw_writel(SPEAR600_ADC_SCAN_RATE_LO(rate),
+ &st->adc_base_spear6xx->scan_rate_lo);
+ __raw_writel(SPEAR600_ADC_SCAN_RATE_HI(rate),
+ &st->adc_base_spear6xx->scan_rate_hi);
} else {
- __raw_writel(rate, &info->adc_base_spear3xx->scan_rate);
+ __raw_writel(rate, &st->adc_base_spear3xx->scan_rate);
}
}
-static int spear_read_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int *val,
- int *val2,
- long mask)
+static int spear_adc_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val,
+ int *val2,
+ long mask)
{
- struct spear_adc_info *info = iio_priv(indio_dev);
- u32 scale_mv;
+ struct spear_adc_state *st = iio_priv(indio_dev);
u32 status;
switch (mask) {
case IIO_CHAN_INFO_RAW:
mutex_lock(&indio_dev->mlock);
- status = CHANNEL_NUM(chan->channel) |
- AVG_SAMPLE(info->avg_samples) |
- START_CONVERSION | ADC_ENABLE;
- if (info->vref_external == 0)
- status |= VREF_INTERNAL;
+ status = SPEAR_ADC_STATUS_CHANNEL_NUM(chan->channel) |
+ SPEAR_ADC_STATUS_AVG_SAMPLE(st->avg_samples) |
+ SPEAR_ADC_STATUS_START_CONVERSION |
+ SPEAR_ADC_STATUS_ADC_ENABLE;
+ if (st->vref_external == 0)
+ status |= SPEAR_ADC_STATUS_VREF_INTERNAL;
- spear_adc_set_status(info, status);
- wait_for_completion(&info->completion); /* set by ISR */
- *val = info->value;
+ spear_adc_set_status(st, status);
+ wait_for_completion(&st->completion); /* set by ISR */
+ *val = st->value;
mutex_unlock(&indio_dev->mlock);
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
- scale_mv = (info->vref_external * 1000) >> DATA_BITS;
- *val = scale_mv / 1000;
- *val2 = (scale_mv % 1000) * 1000;
- return IIO_VAL_INT_PLUS_MICRO;
+ *val = st->vref_external;
+ *val2 = SPEAR_ADC_DATA_BITS;
+ return IIO_VAL_FRACTIONAL_LOG2;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ *val = st->current_clk;
+ return IIO_VAL_INT;
}
return -EINVAL;
}
+static int spear_adc_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val,
+ int val2,
+ long mask)
+{
+ struct spear_adc_state *st = iio_priv(indio_dev);
+ int ret = 0;
+
+ if (mask != IIO_CHAN_INFO_SAMP_FREQ)
+ return -EINVAL;
+
+ mutex_lock(&indio_dev->mlock);
+
+ if ((val < SPEAR_ADC_CLK_MIN) ||
+ (val > SPEAR_ADC_CLK_MAX) ||
+ (val2 != 0)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ spear_adc_set_clk(st, val);
+
+out:
+ mutex_unlock(&indio_dev->mlock);
+ return ret;
+}
+
#define SPEAR_ADC_CHAN(idx) { \
.type = IIO_VOLTAGE, \
.indexed = 1, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),\
.channel = idx, \
- .scan_type = { \
- .sign = 'u', \
- .storagebits = 16, \
- }, \
}
static const struct iio_chan_spec spear_adc_iio_channels[] = {
@@ -202,92 +226,34 @@ static const struct iio_chan_spec spear_adc_iio_channels[] = {
static irqreturn_t spear_adc_isr(int irq, void *dev_id)
{
- struct spear_adc_info *info = (struct spear_adc_info *)dev_id;
+ struct spear_adc_state *st = (struct spear_adc_state *)dev_id;
/* Read value to clear IRQ */
- info->value = spear_adc_get_average(info);
- complete(&info->completion);
+ st->value = spear_adc_get_average(st);
+ complete(&st->completion);
return IRQ_HANDLED;
}
-static int spear_adc_configure(struct spear_adc_info *info)
+static int spear_adc_configure(struct spear_adc_state *st)
{
int i;
/* Reset ADC core */
- spear_adc_set_status(info, 0);
- __raw_writel(0, &info->adc_base_spear6xx->clk);
+ spear_adc_set_status(st, 0);
+ __raw_writel(0, &st->adc_base_spear6xx->clk);
for (i = 0; i < 8; i++)
- spear_adc_set_ctrl(info, i, 0);
- spear_adc_set_scanrate(info, 0);
+ spear_adc_set_ctrl(st, i, 0);
+ spear_adc_set_scanrate(st, 0);
- spear_adc_set_clk(info, info->sampling_freq);
+ spear_adc_set_clk(st, st->sampling_freq);
return 0;
}
-static ssize_t spear_adc_read_frequency(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct spear_adc_info *info = iio_priv(indio_dev);
-
- return sprintf(buf, "%d\n", info->current_clk);
-}
-
-static ssize_t spear_adc_write_frequency(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct spear_adc_info *info = iio_priv(indio_dev);
- u32 clk_high, clk_low, count;
- u32 apb_clk = clk_get_rate(info->clk);
- unsigned long lval;
- int ret;
-
- ret = kstrtoul(buf, 10, &lval);
- if (ret)
- return ret;
-
- mutex_lock(&indio_dev->mlock);
-
- if ((lval < CLK_MIN) || (lval > CLK_MAX)) {
- ret = -EINVAL;
- goto out;
- }
-
- count = (apb_clk + lval - 1) / lval;
- clk_low = count / 2;
- clk_high = count - clk_low;
- info->current_clk = apb_clk / count;
- spear_adc_set_clk(info, lval);
-
-out:
- mutex_unlock(&indio_dev->mlock);
-
- return ret ? ret : len;
-}
-
-static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
- spear_adc_read_frequency,
- spear_adc_write_frequency);
-
-static struct attribute *spear_attributes[] = {
- &iio_dev_attr_sampling_frequency.dev_attr.attr,
- NULL
-};
-
-static const struct attribute_group spear_attribute_group = {
- .attrs = spear_attributes,
-};
-
-static const struct iio_info spear_adc_iio_info = {
- .read_raw = &spear_read_raw,
- .attrs = &spear_attribute_group,
+static const struct iio_info spear_adc_info = {
+ .read_raw = &spear_adc_read_raw,
+ .write_raw = &spear_adc_write_raw,
.driver_module = THIS_MODULE,
};
@@ -295,122 +261,117 @@ static int spear_adc_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct device *dev = &pdev->dev;
- struct spear_adc_info *info;
- struct iio_dev *iodev = NULL;
+ struct spear_adc_state *st;
+ struct iio_dev *indio_dev = NULL;
int ret = -ENODEV;
int irq;
- iodev = iio_device_alloc(sizeof(struct spear_adc_info));
- if (!iodev) {
+ indio_dev = devm_iio_device_alloc(dev, sizeof(struct spear_adc_state));
+ if (!indio_dev) {
dev_err(dev, "failed allocating iio device\n");
- ret = -ENOMEM;
- goto errout1;
+ return -ENOMEM;
}
- info = iio_priv(iodev);
- info->np = np;
+ st = iio_priv(indio_dev);
+ st->np = np;
/*
* SPEAr600 has a different register layout than other SPEAr SoC's
* (e.g. SPEAr3xx). Let's provide two register base addresses
* to support multi-arch kernels.
*/
- info->adc_base_spear6xx = of_iomap(np, 0);
- if (!info->adc_base_spear6xx) {
+ st->adc_base_spear6xx = of_iomap(np, 0);
+ if (!st->adc_base_spear6xx) {
dev_err(dev, "failed mapping memory\n");
- ret = -ENOMEM;
- goto errout2;
+ return -ENOMEM;
}
- info->adc_base_spear3xx =
- (struct adc_regs_spear3xx *)info->adc_base_spear6xx;
+ st->adc_base_spear3xx =
+ (struct adc_regs_spear3xx __iomem *)st->adc_base_spear6xx;
- info->clk = clk_get(dev, NULL);
- if (IS_ERR(info->clk)) {
+ st->clk = clk_get(dev, NULL);
+ if (IS_ERR(st->clk)) {
dev_err(dev, "failed getting clock\n");
- goto errout3;
+ goto errout1;
}
- ret = clk_prepare_enable(info->clk);
+ ret = clk_prepare_enable(st->clk);
if (ret) {
dev_err(dev, "failed enabling clock\n");
- goto errout4;
+ goto errout2;
}
irq = platform_get_irq(pdev, 0);
- if ((irq < 0) || (irq >= NR_IRQS)) {
+ if (irq <= 0) {
dev_err(dev, "failed getting interrupt resource\n");
ret = -EINVAL;
- goto errout5;
+ goto errout3;
}
- ret = devm_request_irq(dev, irq, spear_adc_isr, 0, MOD_NAME, info);
+ ret = devm_request_irq(dev, irq, spear_adc_isr, 0, SPEAR_ADC_MOD_NAME,
+ st);
if (ret < 0) {
dev_err(dev, "failed requesting interrupt\n");
- goto errout5;
+ goto errout3;
}
if (of_property_read_u32(np, "sampling-frequency",
- &info->sampling_freq)) {
+ &st->sampling_freq)) {
dev_err(dev, "sampling-frequency missing in DT\n");
ret = -EINVAL;
- goto errout5;
+ goto errout3;
}
/*
* Optional avg_samples defaults to 0, resulting in single data
* conversion
*/
- of_property_read_u32(np, "average-samples", &info->avg_samples);
+ of_property_read_u32(np, "average-samples", &st->avg_samples);
/*
* Optional vref_external defaults to 0, resulting in internal vref
* selection
*/
- of_property_read_u32(np, "vref-external", &info->vref_external);
+ of_property_read_u32(np, "vref-external", &st->vref_external);
- spear_adc_configure(info);
+ spear_adc_configure(st);
- platform_set_drvdata(pdev, iodev);
+ platform_set_drvdata(pdev, indio_dev);
- init_completion(&info->completion);
+ init_completion(&st->completion);
- iodev->name = MOD_NAME;
- iodev->dev.parent = dev;
- iodev->info = &spear_adc_iio_info;
- iodev->modes = INDIO_DIRECT_MODE;
- iodev->channels = spear_adc_iio_channels;
- iodev->num_channels = ARRAY_SIZE(spear_adc_iio_channels);
+ indio_dev->name = SPEAR_ADC_MOD_NAME;
+ indio_dev->dev.parent = dev;
+ indio_dev->info = &spear_adc_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = spear_adc_iio_channels;
+ indio_dev->num_channels = ARRAY_SIZE(spear_adc_iio_channels);
- ret = iio_device_register(iodev);
+ ret = iio_device_register(indio_dev);
if (ret)
- goto errout5;
+ goto errout3;
dev_info(dev, "SPEAR ADC driver loaded, IRQ %d\n", irq);
return 0;
-errout5:
- clk_disable_unprepare(info->clk);
-errout4:
- clk_put(info->clk);
errout3:
- iounmap(info->adc_base_spear6xx);
+ clk_disable_unprepare(st->clk);
errout2:
- iio_device_free(iodev);
+ clk_put(st->clk);
errout1:
+ iounmap(st->adc_base_spear6xx);
return ret;
}
static int spear_adc_remove(struct platform_device *pdev)
{
- struct iio_dev *iodev = platform_get_drvdata(pdev);
- struct spear_adc_info *info = iio_priv(iodev);
+ struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+ struct spear_adc_state *st = iio_priv(indio_dev);
- iio_device_unregister(iodev);
- clk_disable_unprepare(info->clk);
- clk_put(info->clk);
- iounmap(info->adc_base_spear6xx);
- iio_device_free(iodev);
+ iio_device_unregister(indio_dev);
+ clk_disable_unprepare(st->clk);
+ clk_put(st->clk);
+ iounmap(st->adc_base_spear6xx);
return 0;
}
@@ -427,7 +388,7 @@ static struct platform_driver spear_adc_driver = {
.probe = spear_adc_probe,
.remove = spear_adc_remove,
.driver = {
- .name = MOD_NAME,
+ .name = SPEAR_ADC_MOD_NAME,
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(spear_adc_dt_ids),
},
diff --git a/drivers/staging/iio/addac/adt7316-i2c.c b/drivers/staging/iio/addac/adt7316-i2c.c
index ce7d91cb331..75ddd4f801a 100644
--- a/drivers/staging/iio/addac/adt7316-i2c.c
+++ b/drivers/staging/iio/addac/adt7316-i2c.c
@@ -108,11 +108,6 @@ static int adt7316_i2c_probe(struct i2c_client *client,
return adt7316_probe(&client->dev, &bus, id->name);
}
-static int adt7316_i2c_remove(struct i2c_client *client)
-{
- return adt7316_remove(&client->dev);
-}
-
static const struct i2c_device_id adt7316_i2c_id[] = {
{ "adt7316", 0 },
{ "adt7317", 0 },
@@ -132,12 +127,10 @@ static struct i2c_driver adt7316_driver = {
.owner = THIS_MODULE,
},
.probe = adt7316_i2c_probe,
- .remove = adt7316_i2c_remove,
.id_table = adt7316_i2c_id,
};
module_i2c_driver(adt7316_driver);
MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
-MODULE_DESCRIPTION("I2C bus driver for Analog Devices ADT7316/7/9 and"
- "ADT7516/7/8 digital temperature sensor, ADC and DAC");
+MODULE_DESCRIPTION("I2C bus driver for Analog Devices ADT7316/7/9 and ADT7516/7/8 digital temperature sensor, ADC and DAC");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/addac/adt7316-spi.c b/drivers/staging/iio/addac/adt7316-spi.c
index 0db8ef5835a..e480abb72e4 100644
--- a/drivers/staging/iio/addac/adt7316-spi.c
+++ b/drivers/staging/iio/addac/adt7316-spi.c
@@ -116,11 +116,6 @@ static int adt7316_spi_probe(struct spi_device *spi_dev)
return adt7316_probe(&spi_dev->dev, &bus, spi_dev->modalias);
}
-static int adt7316_spi_remove(struct spi_device *spi_dev)
-{
- return adt7316_remove(&spi_dev->dev);
-}
-
static const struct spi_device_id adt7316_spi_id[] = {
{ "adt7316", 0 },
{ "adt7317", 0 },
@@ -140,12 +135,10 @@ static struct spi_driver adt7316_driver = {
.owner = THIS_MODULE,
},
.probe = adt7316_spi_probe,
- .remove = adt7316_spi_remove,
.id_table = adt7316_spi_id,
};
module_spi_driver(adt7316_driver);
MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
-MODULE_DESCRIPTION("SPI bus driver for Analog Devices ADT7316/7/8 and"
- "ADT7516/7/9 digital temperature sensor, ADC and DAC");
+MODULE_DESCRIPTION("SPI bus driver for Analog Devices ADT7316/7/8 and ADT7516/7/9 digital temperature sensor, ADC and DAC");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c
index 506b5a7d96c..5f1770e6f6c 100644
--- a/drivers/staging/iio/addac/adt7316.c
+++ b/drivers/staging/iio/addac/adt7316.c
@@ -172,7 +172,7 @@
#define ID_ADT75XX 0x10
/*
- * struct adt7316_chip_info - chip specifc information
+ * struct adt7316_chip_info - chip specific information
*/
struct adt7316_chip_info {
@@ -208,7 +208,7 @@ struct adt7316_chip_info {
(ADT7316_TEMP_INT_MASK)
/*
- * struct adt7316_chip_info - chip specifc information
+ * struct adt7316_chip_info - chip specific information
*/
struct adt7316_limit_regs {
@@ -412,13 +412,13 @@ static ssize_t adt7316_store_ad_channel(struct device *dev,
struct iio_dev *dev_info = dev_to_iio_dev(dev);
struct adt7316_chip_info *chip = iio_priv(dev_info);
u8 config2;
- unsigned long data = 0;
+ u8 data;
int ret;
if (!(chip->config2 & ADT7316_AD_SINGLE_CH_MODE))
return -EPERM;
- ret = strict_strtoul(buf, 10, &data);
+ ret = kstrtou8(buf, 10, &data);
if (ret)
return -EINVAL;
@@ -551,31 +551,6 @@ static IIO_DEVICE_ATTR(enable_smbus_timeout, S_IRUGO | S_IWUSR,
adt7316_store_enable_smbus_timeout,
0);
-
-static ssize_t adt7316_store_reset(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- struct iio_dev *dev_info = dev_to_iio_dev(dev);
- struct adt7316_chip_info *chip = iio_priv(dev_info);
- u8 config2;
- int ret;
-
- config2 = chip->config2 | ADT7316_RESET;
-
- ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG2, config2);
- if (ret)
- return -EIO;
-
- return len;
-}
-
-static IIO_DEVICE_ATTR(reset, S_IWUSR,
- NULL,
- adt7316_store_reset,
- 0);
-
static ssize_t adt7316_show_powerdown(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -848,10 +823,10 @@ static ssize_t adt7316_store_DAC_2Vref_ch_mask(struct device *dev,
struct iio_dev *dev_info = dev_to_iio_dev(dev);
struct adt7316_chip_info *chip = iio_priv(dev_info);
u8 dac_config;
- unsigned long data = 0;
+ u8 data;
int ret;
- ret = strict_strtoul(buf, 16, &data);
+ ret = kstrtou8(buf, 16, &data);
if (ret || data > ADT7316_DA_2VREF_CH_MASK)
return -EINVAL;
@@ -884,11 +859,14 @@ static ssize_t adt7316_show_DAC_update_mode(struct device *dev,
else {
switch (chip->dac_config & ADT7316_DA_EN_MODE_MASK) {
case ADT7316_DA_EN_MODE_SINGLE:
- return sprintf(buf, "0 - auto at any MSB DAC writing\n");
+ return sprintf(buf,
+ "0 - auto at any MSB DAC writing\n");
case ADT7316_DA_EN_MODE_AB_CD:
- return sprintf(buf, "1 - auto at MSB DAC AB and CD writing\n");
+ return sprintf(buf,
+ "1 - auto at MSB DAC AB and CD writing\n");
case ADT7316_DA_EN_MODE_ABCD:
- return sprintf(buf, "2 - auto at MSB DAC ABCD writing\n");
+ return sprintf(buf,
+ "2 - auto at MSB DAC ABCD writing\n");
default: /* ADT7316_DA_EN_MODE_LDAC */
return sprintf(buf, "3 - manual\n");
}
@@ -903,13 +881,13 @@ static ssize_t adt7316_store_DAC_update_mode(struct device *dev,
struct iio_dev *dev_info = dev_to_iio_dev(dev);
struct adt7316_chip_info *chip = iio_priv(dev_info);
u8 dac_config;
- unsigned long data;
+ u8 data;
int ret;
if (!(chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA))
return -EPERM;
- ret = strict_strtoul(buf, 10, &data);
+ ret = kstrtou8(buf, 10, &data);
if (ret || data > ADT7316_DA_EN_MODE_MASK)
return -EINVAL;
@@ -958,7 +936,7 @@ static ssize_t adt7316_store_update_DAC(struct device *dev,
struct iio_dev *dev_info = dev_to_iio_dev(dev);
struct adt7316_chip_info *chip = iio_priv(dev_info);
u8 ldac_config;
- unsigned long data;
+ u8 data;
int ret;
if (chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA) {
@@ -966,7 +944,7 @@ static ssize_t adt7316_store_update_DAC(struct device *dev,
ADT7316_DA_EN_MODE_LDAC)
return -EPERM;
- ret = strict_strtoul(buf, 16, &data);
+ ret = kstrtou8(buf, 16, &data);
if (ret || data > ADT7316_LDAC_EN_DA_MASK)
return -EINVAL;
@@ -1104,11 +1082,11 @@ static ssize_t adt7316_store_DAC_internal_Vref(struct device *dev,
struct iio_dev *dev_info = dev_to_iio_dev(dev);
struct adt7316_chip_info *chip = iio_priv(dev_info);
u8 ldac_config;
- unsigned long data;
+ u8 data;
int ret;
if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) {
- ret = strict_strtoul(buf, 16, &data);
+ ret = kstrtou8(buf, 16, &data);
if (ret || data > 3)
return -EINVAL;
@@ -1118,7 +1096,7 @@ static ssize_t adt7316_store_DAC_internal_Vref(struct device *dev,
else if (data & 0x2)
ldac_config |= ADT7516_DAC_CD_IN_VREF;
} else {
- ret = strict_strtoul(buf, 16, &data);
+ ret = kstrtou8(buf, 16, &data);
if (ret)
return -EINVAL;
@@ -1127,7 +1105,8 @@ static ssize_t adt7316_store_DAC_internal_Vref(struct device *dev,
ldac_config = chip->ldac_config | ADT7316_DAC_IN_VREF;
}
- ret = chip->bus.write(chip->bus.client, ADT7316_LDAC_CONFIG, ldac_config);
+ ret = chip->bus.write(chip->bus.client, ADT7316_LDAC_CONFIG,
+ ldac_config);
if (ret)
return -EIO;
@@ -1249,7 +1228,8 @@ static ssize_t adt7316_show_ex_temp_AIN1(struct device *dev,
return adt7316_show_ad(chip, ADT7316_AD_SINGLE_CH_EX, buf);
}
-static IIO_DEVICE_ATTR(ex_temp_AIN1, S_IRUGO, adt7316_show_ex_temp_AIN1, NULL, 0);
+static IIO_DEVICE_ATTR(ex_temp_AIN1, S_IRUGO, adt7316_show_ex_temp_AIN1,
+ NULL, 0);
static IIO_DEVICE_ATTR(ex_temp, S_IRUGO, adt7316_show_ex_temp_AIN1, NULL, 0);
static ssize_t adt7316_show_AIN2(struct device *dev,
@@ -1306,11 +1286,11 @@ static ssize_t adt7316_show_temp_offset(struct adt7316_chip_info *chip,
static ssize_t adt7316_store_temp_offset(struct adt7316_chip_info *chip,
int offset_addr, const char *buf, size_t len)
{
- long data;
+ int data;
u8 val;
int ret;
- ret = strict_strtol(buf, 10, &data);
+ ret = kstrtoint(buf, 10, &data);
if (ret || data > 127 || data < -128)
return -EINVAL;
@@ -1344,7 +1324,8 @@ static ssize_t adt7316_store_in_temp_offset(struct device *dev,
struct iio_dev *dev_info = dev_to_iio_dev(dev);
struct adt7316_chip_info *chip = iio_priv(dev_info);
- return adt7316_store_temp_offset(chip, ADT7316_IN_TEMP_OFFSET, buf, len);
+ return adt7316_store_temp_offset(chip, ADT7316_IN_TEMP_OFFSET, buf,
+ len);
}
static IIO_DEVICE_ATTR(in_temp_offset, S_IRUGO | S_IWUSR,
@@ -1369,7 +1350,8 @@ static ssize_t adt7316_store_ex_temp_offset(struct device *dev,
struct iio_dev *dev_info = dev_to_iio_dev(dev);
struct adt7316_chip_info *chip = iio_priv(dev_info);
- return adt7316_store_temp_offset(chip, ADT7316_EX_TEMP_OFFSET, buf, len);
+ return adt7316_store_temp_offset(chip, ADT7316_EX_TEMP_OFFSET, buf,
+ len);
}
static IIO_DEVICE_ATTR(ex_temp_offset, S_IRUGO | S_IWUSR,
@@ -1467,7 +1449,7 @@ static ssize_t adt7316_store_DAC(struct adt7316_chip_info *chip,
int channel, const char *buf, size_t len)
{
u8 msb, lsb, offset;
- unsigned long data;
+ u16 data;
int ret;
if (channel >= ADT7316_DA_MSB_DATA_REGS ||
@@ -1479,7 +1461,7 @@ static ssize_t adt7316_store_DAC(struct adt7316_chip_info *chip,
offset = chip->dac_bits - 8;
- ret = strict_strtoul(buf, 10, &data);
+ ret = kstrtou16(buf, 10, &data);
if (ret || data >= (1 << chip->dac_bits))
return -EINVAL;
@@ -1675,7 +1657,6 @@ static IIO_DEVICE_ATTR(bus_type, S_IRUGO, adt7316_show_bus_type, NULL, 0);
static struct attribute *adt7316_attributes[] = {
&iio_dev_attr_all_modes.dev_attr.attr,
&iio_dev_attr_mode.dev_attr.attr,
- &iio_dev_attr_reset.dev_attr.attr,
&iio_dev_attr_enabled.dev_attr.attr,
&iio_dev_attr_ad_channel.dev_attr.attr,
&iio_dev_attr_all_ad_channels.dev_attr.attr,
@@ -1719,7 +1700,6 @@ static struct attribute *adt7516_attributes[] = {
&iio_dev_attr_all_modes.dev_attr.attr,
&iio_dev_attr_mode.dev_attr.attr,
&iio_dev_attr_select_ex_temp.dev_attr.attr,
- &iio_dev_attr_reset.dev_attr.attr,
&iio_dev_attr_enabled.dev_attr.attr,
&iio_dev_attr_ad_channel.dev_attr.attr,
&iio_dev_attr_all_ad_channels.dev_attr.attr,
@@ -1857,11 +1837,11 @@ static ssize_t adt7316_set_int_mask(struct device *dev,
{
struct iio_dev *dev_info = dev_to_iio_dev(dev);
struct adt7316_chip_info *chip = iio_priv(dev_info);
- unsigned long data;
+ u16 data;
int ret;
u8 mask;
- ret = strict_strtoul(buf, 16, &data);
+ ret = kstrtou16(buf, 16, &data);
if (ret || data >= ADT7316_VDD_INT_MASK + 1)
return -EINVAL;
@@ -1928,7 +1908,7 @@ static inline ssize_t adt7316_set_ad_bound(struct device *dev,
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
struct iio_dev *dev_info = dev_to_iio_dev(dev);
struct adt7316_chip_info *chip = iio_priv(dev_info);
- long data;
+ int data;
u8 val;
int ret;
@@ -1936,7 +1916,7 @@ static inline ssize_t adt7316_set_ad_bound(struct device *dev,
this_attr->address > ADT7316_EX_TEMP_LOW)
return -EPERM;
- ret = strict_strtol(buf, 10, &data);
+ ret = kstrtoint(buf, 10, &data);
if (ret)
return -EINVAL;
@@ -2133,11 +2113,9 @@ int adt7316_probe(struct device *dev, struct adt7316_bus *bus,
unsigned short *adt7316_platform_data = dev->platform_data;
int ret = 0;
- indio_dev = iio_device_alloc(sizeof(*chip));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*chip));
+ if (!indio_dev)
+ return -ENOMEM;
chip = iio_priv(indio_dev);
/* this is only used for device removal purposes */
dev_set_drvdata(dev, indio_dev);
@@ -2173,63 +2151,39 @@ int adt7316_probe(struct device *dev, struct adt7316_bus *bus,
if (adt7316_platform_data[0])
chip->bus.irq_flags = adt7316_platform_data[0];
- ret = request_threaded_irq(chip->bus.irq,
- NULL,
- &adt7316_event_handler,
- chip->bus.irq_flags | IRQF_ONESHOT,
- indio_dev->name,
- indio_dev);
+ ret = devm_request_threaded_irq(dev, chip->bus.irq,
+ NULL,
+ &adt7316_event_handler,
+ chip->bus.irq_flags |
+ IRQF_ONESHOT,
+ indio_dev->name,
+ indio_dev);
if (ret)
- goto error_free_dev;
+ return ret;
if (chip->bus.irq_flags & IRQF_TRIGGER_HIGH)
chip->config1 |= ADT7316_INT_POLARITY;
}
ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, chip->config1);
- if (ret) {
- ret = -EIO;
- goto error_unreg_irq;
- }
+ if (ret)
+ return -EIO;
ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, chip->config3);
- if (ret) {
- ret = -EIO;
- goto error_unreg_irq;
- }
+ if (ret)
+ return -EIO;
- ret = iio_device_register(indio_dev);
+ ret = devm_iio_device_register(dev, indio_dev);
if (ret)
- goto error_unreg_irq;
+ return ret;
dev_info(dev, "%s temperature sensor, ADC and DAC registered.\n",
indio_dev->name);
return 0;
-
-error_unreg_irq:
- free_irq(chip->bus.irq, indio_dev);
-error_free_dev:
- iio_device_free(indio_dev);
-error_ret:
- return ret;
}
EXPORT_SYMBOL(adt7316_probe);
-int adt7316_remove(struct device *dev)
-{
- struct iio_dev *indio_dev = dev_get_drvdata(dev);
- struct adt7316_chip_info *chip = iio_priv(indio_dev);
-
- iio_device_unregister(indio_dev);
- if (chip->bus.irq)
- free_irq(chip->bus.irq, indio_dev);
- iio_device_free(indio_dev);
-
- return 0;
-}
-EXPORT_SYMBOL(adt7316_remove);
-
MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
MODULE_DESCRIPTION("Analog Devices ADT7316/7/8 and ADT7516/7/9 digital"
" temperature sensor, ADC and DAC driver");
diff --git a/drivers/staging/iio/addac/adt7316.h b/drivers/staging/iio/addac/adt7316.h
index 4d3efff46ae..ec50bf34628 100644
--- a/drivers/staging/iio/addac/adt7316.h
+++ b/drivers/staging/iio/addac/adt7316.h
@@ -18,10 +18,10 @@ struct adt7316_bus {
void *client;
int irq;
int irq_flags;
- int (*read) (void *client, u8 reg, u8 *data);
- int (*write) (void *client, u8 reg, u8 val);
- int (*multi_read) (void *client, u8 first_reg, u8 count, u8 *data);
- int (*multi_write) (void *client, u8 first_reg, u8 count, u8 *data);
+ int (*read)(void *client, u8 reg, u8 *data);
+ int (*write)(void *client, u8 reg, u8 val);
+ int (*multi_read)(void *client, u8 first_reg, u8 count, u8 *data);
+ int (*multi_write)(void *client, u8 first_reg, u8 count, u8 *data);
};
#ifdef CONFIG_PM_SLEEP
@@ -31,6 +31,5 @@ extern const struct dev_pm_ops adt7316_pm_ops;
#define ADT7316_PM_OPS NULL
#endif
int adt7316_probe(struct device *dev, struct adt7316_bus *bus, const char *name);
-int adt7316_remove(struct device *dev);
#endif
diff --git a/drivers/staging/iio/cdc/ad7150.c b/drivers/staging/iio/cdc/ad7150.c
index 687dd2c9143..047af237630 100644
--- a/drivers/staging/iio/cdc/ad7150.c
+++ b/drivers/staging/iio/cdc/ad7150.c
@@ -123,14 +123,14 @@ static int ad7150_read_raw(struct iio_dev *indio_dev,
}
}
-static int ad7150_read_event_config(struct iio_dev *indio_dev, u64 event_code)
+static int ad7150_read_event_config(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan, enum iio_event_type type,
+ enum iio_event_direction dir)
{
int ret;
u8 threshtype;
bool adaptive;
struct ad7150_chip_info *chip = iio_priv(indio_dev);
- int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
- IIO_EV_DIR_RISING);
ret = i2c_smbus_read_byte_data(chip->client, AD7150_CFG);
if (ret < 0)
@@ -139,42 +139,47 @@ static int ad7150_read_event_config(struct iio_dev *indio_dev, u64 event_code)
threshtype = (ret >> 5) & 0x03;
adaptive = !!(ret & 0x80);
- switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+ switch (type) {
case IIO_EV_TYPE_MAG_ADAPTIVE:
- if (rising)
+ if (dir == IIO_EV_DIR_RISING)
return adaptive && (threshtype == 0x1);
else
return adaptive && (threshtype == 0x0);
case IIO_EV_TYPE_THRESH_ADAPTIVE:
- if (rising)
+ if (dir == IIO_EV_DIR_RISING)
return adaptive && (threshtype == 0x3);
else
return adaptive && (threshtype == 0x2);
case IIO_EV_TYPE_THRESH:
- if (rising)
+ if (dir == IIO_EV_DIR_RISING)
return !adaptive && (threshtype == 0x1);
else
return !adaptive && (threshtype == 0x0);
+ default:
+ break;
}
return -EINVAL;
}
/* lock should be held */
-static int ad7150_write_event_params(struct iio_dev *indio_dev, u64 event_code)
+static int ad7150_write_event_params(struct iio_dev *indio_dev,
+ unsigned int chan, enum iio_event_type type,
+ enum iio_event_direction dir)
{
int ret;
u16 value;
u8 sens, timeout;
struct ad7150_chip_info *chip = iio_priv(indio_dev);
- int chan = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
- int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
- IIO_EV_DIR_RISING);
+ int rising = (dir == IIO_EV_DIR_RISING);
+ u64 event_code;
+
+ event_code = IIO_UNMOD_EVENT_CODE(IIO_CAPACITANCE, chan, type, dir);
if (event_code != chip->current_event)
return 0;
- switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+ switch (type) {
/* Note completely different from the adaptive versions */
case IIO_EV_TYPE_THRESH:
value = chip->threshold[rising][chan];
@@ -211,18 +216,20 @@ static int ad7150_write_event_params(struct iio_dev *indio_dev, u64 event_code)
}
static int ad7150_write_event_config(struct iio_dev *indio_dev,
- u64 event_code, int state)
+ const struct iio_chan_spec *chan, enum iio_event_type type,
+ enum iio_event_direction dir, int state)
{
u8 thresh_type, cfg, adaptive;
int ret;
struct ad7150_chip_info *chip = iio_priv(indio_dev);
- int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
- IIO_EV_DIR_RISING);
+ int rising = (dir == IIO_EV_DIR_RISING);
+ u64 event_code;
/* Something must always be turned on */
if (state == 0)
return -EINVAL;
+ event_code = IIO_UNMOD_EVENT_CODE(chan->type, chan->channel, type, dir);
if (event_code == chip->current_event)
return 0;
mutex_lock(&chip->state_lock);
@@ -232,7 +239,7 @@ static int ad7150_write_event_config(struct iio_dev *indio_dev,
cfg = ret & ~((0x03 << 5) | (0x1 << 7));
- switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+ switch (type) {
case IIO_EV_TYPE_MAG_ADAPTIVE:
adaptive = 1;
if (rising)
@@ -268,7 +275,7 @@ static int ad7150_write_event_config(struct iio_dev *indio_dev,
chip->current_event = event_code;
/* update control attributes */
- ret = ad7150_write_event_params(indio_dev, event_code);
+ ret = ad7150_write_event_params(indio_dev, chan->channel, type, dir);
error_ret:
mutex_unlock(&chip->state_lock);
@@ -276,53 +283,52 @@ error_ret:
}
static int ad7150_read_event_value(struct iio_dev *indio_dev,
- u64 event_code,
- int *val)
+ 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)
{
- int chan = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
struct ad7150_chip_info *chip = iio_priv(indio_dev);
- int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
- IIO_EV_DIR_RISING);
+ int rising = (dir == IIO_EV_DIR_RISING);
/* Complex register sharing going on here */
- switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+ switch (type) {
case IIO_EV_TYPE_MAG_ADAPTIVE:
- *val = chip->mag_sensitivity[rising][chan];
- return 0;
-
+ *val = chip->mag_sensitivity[rising][chan->channel];
+ return IIO_VAL_INT;
case IIO_EV_TYPE_THRESH_ADAPTIVE:
- *val = chip->thresh_sensitivity[rising][chan];
- return 0;
-
+ *val = chip->thresh_sensitivity[rising][chan->channel];
+ return IIO_VAL_INT;
case IIO_EV_TYPE_THRESH:
- *val = chip->threshold[rising][chan];
- return 0;
-
+ *val = chip->threshold[rising][chan->channel];
+ return IIO_VAL_INT;
default:
return -EINVAL;
- };
+ }
}
static int ad7150_write_event_value(struct iio_dev *indio_dev,
- u64 event_code,
- int val)
+ 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)
{
int ret;
struct ad7150_chip_info *chip = iio_priv(indio_dev);
- int chan = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
- int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
- IIO_EV_DIR_RISING);
+ int rising = (dir == IIO_EV_DIR_RISING);
mutex_lock(&chip->state_lock);
- switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+ switch (type) {
case IIO_EV_TYPE_MAG_ADAPTIVE:
- chip->mag_sensitivity[rising][chan] = val;
+ chip->mag_sensitivity[rising][chan->channel] = val;
break;
case IIO_EV_TYPE_THRESH_ADAPTIVE:
- chip->thresh_sensitivity[rising][chan] = val;
+ chip->thresh_sensitivity[rising][chan->channel] = val;
break;
case IIO_EV_TYPE_THRESH:
- chip->threshold[rising][chan] = val;
+ chip->threshold[rising][chan->channel] = val;
break;
default:
ret = -EINVAL;
@@ -330,7 +336,7 @@ static int ad7150_write_event_value(struct iio_dev *indio_dev,
}
/* write back if active */
- ret = ad7150_write_event_params(indio_dev, event_code);
+ ret = ad7150_write_event_params(indio_dev, chan->channel, type, dir);
error_ret:
mutex_unlock(&chip->state_lock);
@@ -374,17 +380,22 @@ static ssize_t ad7150_store_timeout(struct device *dev,
struct ad7150_chip_info *chip = iio_priv(indio_dev);
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
int chan = IIO_EVENT_CODE_EXTRACT_CHAN(this_attr->address);
- int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(this_attr->address) ==
- IIO_EV_DIR_RISING);
+ enum iio_event_direction dir;
+ enum iio_event_type type;
+ int rising;
u8 data;
int ret;
+ type = IIO_EVENT_CODE_EXTRACT_TYPE(this_attr->address);
+ dir = IIO_EVENT_CODE_EXTRACT_DIR(this_attr->address);
+ rising = (dir == IIO_EV_DIR_RISING);
+
ret = kstrtou8(buf, 10, &data);
if (ret < 0)
return ret;
mutex_lock(&chip->state_lock);
- switch (IIO_EVENT_CODE_EXTRACT_TYPE(this_attr->address)) {
+ switch (type) {
case IIO_EV_TYPE_MAG_ADAPTIVE:
chip->mag_timeout[rising][chan] = data;
break;
@@ -396,7 +407,7 @@ static ssize_t ad7150_store_timeout(struct device *dev,
goto error_ret;
}
- ret = ad7150_write_event_params(indio_dev, this_attr->address);
+ ret = ad7150_write_event_params(indio_dev, chan, type, dir);
error_ret:
mutex_unlock(&chip->state_lock);
@@ -424,6 +435,40 @@ static AD7150_TIMEOUT(0, thresh_adaptive, falling, THRESH_ADAPTIVE, FALLING);
static AD7150_TIMEOUT(1, thresh_adaptive, rising, THRESH_ADAPTIVE, RISING);
static AD7150_TIMEOUT(1, thresh_adaptive, falling, THRESH_ADAPTIVE, FALLING);
+static const struct iio_event_spec ad7150_events[] = {
+ {
+ .type = IIO_EV_TYPE_THRESH,
+ .dir = IIO_EV_DIR_RISING,
+ .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+ BIT(IIO_EV_INFO_ENABLE),
+ }, {
+ .type = IIO_EV_TYPE_THRESH,
+ .dir = IIO_EV_DIR_FALLING,
+ .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+ BIT(IIO_EV_INFO_ENABLE),
+ }, {
+ .type = IIO_EV_TYPE_THRESH_ADAPTIVE,
+ .dir = IIO_EV_DIR_RISING,
+ .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+ BIT(IIO_EV_INFO_ENABLE),
+ }, {
+ .type = IIO_EV_TYPE_THRESH_ADAPTIVE,
+ .dir = IIO_EV_DIR_FALLING,
+ .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+ BIT(IIO_EV_INFO_ENABLE),
+ }, {
+ .type = IIO_EV_TYPE_MAG_ADAPTIVE,
+ .dir = IIO_EV_DIR_RISING,
+ .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+ BIT(IIO_EV_INFO_ENABLE),
+ }, {
+ .type = IIO_EV_TYPE_MAG_ADAPTIVE,
+ .dir = IIO_EV_DIR_FALLING,
+ .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+ BIT(IIO_EV_INFO_ENABLE),
+ },
+};
+
static const struct iio_chan_spec ad7150_channels[] = {
{
.type = IIO_CAPACITANCE,
@@ -431,26 +476,16 @@ static const struct iio_chan_spec ad7150_channels[] = {
.channel = 0,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_AVERAGE_RAW),
- .event_mask =
- IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) |
- IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING) |
- IIO_EV_BIT(IIO_EV_TYPE_THRESH_ADAPTIVE, IIO_EV_DIR_RISING) |
- IIO_EV_BIT(IIO_EV_TYPE_THRESH_ADAPTIVE, IIO_EV_DIR_FALLING) |
- IIO_EV_BIT(IIO_EV_TYPE_MAG_ADAPTIVE, IIO_EV_DIR_RISING) |
- IIO_EV_BIT(IIO_EV_TYPE_MAG_ADAPTIVE, IIO_EV_DIR_FALLING)
+ .event_spec = ad7150_events,
+ .num_event_specs = ARRAY_SIZE(ad7150_events),
}, {
.type = IIO_CAPACITANCE,
.indexed = 1,
.channel = 1,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_AVERAGE_RAW),
- .event_mask =
- IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) |
- IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING) |
- IIO_EV_BIT(IIO_EV_TYPE_THRESH_ADAPTIVE, IIO_EV_DIR_RISING) |
- IIO_EV_BIT(IIO_EV_TYPE_THRESH_ADAPTIVE, IIO_EV_DIR_FALLING) |
- IIO_EV_BIT(IIO_EV_TYPE_MAG_ADAPTIVE, IIO_EV_DIR_RISING) |
- IIO_EV_BIT(IIO_EV_TYPE_MAG_ADAPTIVE, IIO_EV_DIR_FALLING)
+ .event_spec = ad7150_events,
+ .num_event_specs = ARRAY_SIZE(ad7150_events),
},
};
@@ -558,11 +593,9 @@ static int ad7150_probe(struct i2c_client *client,
struct ad7150_chip_info *chip;
struct iio_dev *indio_dev;
- indio_dev = iio_device_alloc(sizeof(*chip));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
+ if (!indio_dev)
+ return -ENOMEM;
chip = iio_priv(indio_dev);
mutex_init(&chip->state_lock);
/* this is only used for device removal purposes */
@@ -581,7 +614,7 @@ static int ad7150_probe(struct i2c_client *client,
indio_dev->modes = INDIO_DIRECT_MODE;
if (client->irq) {
- ret = request_threaded_irq(client->irq,
+ ret = devm_request_threaded_irq(&client->dev, client->irq,
NULL,
&ad7150_event_handler,
IRQF_TRIGGER_RISING |
@@ -590,11 +623,11 @@ static int ad7150_probe(struct i2c_client *client,
"ad7150_irq1",
indio_dev);
if (ret)
- goto error_free_dev;
+ return ret;
}
if (client->dev.platform_data) {
- ret = request_threaded_irq(*(unsigned int *)
+ ret = devm_request_threaded_irq(&client->dev, *(unsigned int *)
client->dev.platform_data,
NULL,
&ad7150_event_handler,
@@ -604,28 +637,17 @@ static int ad7150_probe(struct i2c_client *client,
"ad7150_irq2",
indio_dev);
if (ret)
- goto error_free_irq;
+ return ret;
}
ret = iio_device_register(indio_dev);
if (ret)
- goto error_free_irq2;
+ return ret;
dev_info(&client->dev, "%s capacitive sensor registered,irq: %d\n",
id->name, client->irq);
return 0;
-error_free_irq2:
- if (client->dev.platform_data)
- free_irq(*(unsigned int *)client->dev.platform_data,
- indio_dev);
-error_free_irq:
- if (client->irq)
- free_irq(client->irq, indio_dev);
-error_free_dev:
- iio_device_free(indio_dev);
-error_ret:
- return ret;
}
static int ad7150_remove(struct i2c_client *client)
@@ -633,13 +655,6 @@ static int ad7150_remove(struct i2c_client *client)
struct iio_dev *indio_dev = i2c_get_clientdata(client);
iio_device_unregister(indio_dev);
- if (client->irq)
- free_irq(client->irq, indio_dev);
-
- if (client->dev.platform_data)
- free_irq(*(unsigned int *)client->dev.platform_data, indio_dev);
-
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/cdc/ad7152.c b/drivers/staging/iio/cdc/ad7152.c
index 1d7c5283a85..87110d940e9 100644
--- a/drivers/staging/iio/cdc/ad7152.c
+++ b/drivers/staging/iio/cdc/ad7152.c
@@ -78,7 +78,7 @@ enum {
};
/*
- * struct ad7152_chip_info - chip specifc information
+ * struct ad7152_chip_info - chip specific information
*/
struct ad7152_chip_info {
@@ -481,11 +481,9 @@ static int ad7152_probe(struct i2c_client *client,
struct ad7152_chip_info *chip;
struct iio_dev *indio_dev;
- indio_dev = iio_device_alloc(sizeof(*chip));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
+ if (!indio_dev)
+ return -ENOMEM;
chip = iio_priv(indio_dev);
/* this is only used for device removal purposes */
i2c_set_clientdata(client, indio_dev);
@@ -506,16 +504,11 @@ static int ad7152_probe(struct i2c_client *client,
ret = iio_device_register(indio_dev);
if (ret)
- goto error_free_dev;
+ return ret;
dev_err(&client->dev, "%s capacitive sensor registered\n", id->name);
return 0;
-
-error_free_dev:
- iio_device_free(indio_dev);
-error_ret:
- return ret;
}
static int ad7152_remove(struct i2c_client *client)
@@ -523,7 +516,6 @@ static int ad7152_remove(struct i2c_client *client)
struct iio_dev *indio_dev = i2c_get_clientdata(client);
iio_device_unregister(indio_dev);
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/cdc/ad7746.c b/drivers/staging/iio/cdc/ad7746.c
index 94f9ca726d1..e6e9eaa9eab 100644
--- a/drivers/staging/iio/cdc/ad7746.c
+++ b/drivers/staging/iio/cdc/ad7746.c
@@ -91,7 +91,7 @@
#define AD7746_CAPDAC_DACP(x) ((x) & 0x7F)
/*
- * struct ad7746_chip_info - chip specifc information
+ * struct ad7746_chip_info - chip specific information
*/
struct ad7746_chip_info {
@@ -105,6 +105,11 @@ struct ad7746_chip_info {
u8 vt_setup;
u8 capdac[2][2];
s8 capdac_set;
+
+ union {
+ __be32 d32;
+ u8 d8[4];
+ } data ____cacheline_aligned;
};
enum ad7746_chan {
@@ -566,11 +571,6 @@ static int ad7746_read_raw(struct iio_dev *indio_dev,
int ret, delay;
u8 regval, reg;
- union {
- u32 d32;
- u8 d8[4];
- } data;
-
mutex_lock(&indio_dev->mlock);
switch (mask) {
@@ -591,12 +591,12 @@ static int ad7746_read_raw(struct iio_dev *indio_dev,
/* Now read the actual register */
ret = i2c_smbus_read_i2c_block_data(chip->client,
- chan->address >> 8, 3, &data.d8[1]);
+ chan->address >> 8, 3, &chip->data.d8[1]);
if (ret < 0)
goto out;
- *val = (be32_to_cpu(data.d32) & 0xFFFFFF) - 0x800000;
+ *val = (be32_to_cpu(chip->data.d32) & 0xFFFFFF) - 0x800000;
switch (chan->type) {
case IIO_TEMP:
@@ -656,20 +656,21 @@ static int ad7746_read_raw(struct iio_dev *indio_dev,
switch (chan->type) {
case IIO_CAPACITANCE:
/* 8.192pf / 2^24 */
- *val2 = 488;
*val = 0;
+ *val2 = 488;
+ ret = IIO_VAL_INT_PLUS_NANO;
break;
case IIO_VOLTAGE:
/* 1170mV / 2^23 */
- *val2 = 139475;
- *val = 0;
+ *val = 1170;
+ *val2 = 23;
+ ret = IIO_VAL_FRACTIONAL_LOG2;
break;
default:
- ret = -EINVAL;
- goto out;
+ ret = -EINVAL;
+ break;
}
- ret = IIO_VAL_INT_PLUS_NANO;
break;
default:
ret = -EINVAL;
@@ -699,11 +700,9 @@ static int ad7746_probe(struct i2c_client *client,
int ret = 0;
unsigned char regval = 0;
- indio_dev = iio_device_alloc(sizeof(*chip));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
+ if (!indio_dev)
+ return -ENOMEM;
chip = iio_priv(indio_dev);
/* this is only used for device removal purposes */
i2c_set_clientdata(client, indio_dev);
@@ -748,20 +747,15 @@ static int ad7746_probe(struct i2c_client *client,
ret = i2c_smbus_write_byte_data(chip->client,
AD7746_REG_EXC_SETUP, regval);
if (ret < 0)
- goto error_free_dev;
+ return ret;
ret = iio_device_register(indio_dev);
if (ret)
- goto error_free_dev;
+ return ret;
dev_info(&client->dev, "%s capacitive sensor registered\n", id->name);
return 0;
-
-error_free_dev:
- iio_device_free(indio_dev);
-error_ret:
- return ret;
}
static int ad7746_remove(struct i2c_client *client)
@@ -769,7 +763,6 @@ static int ad7746_remove(struct i2c_client *client)
struct iio_dev *indio_dev = i2c_get_clientdata(client);
iio_device_unregister(indio_dev);
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/frequency/ad5930.c b/drivers/staging/iio/frequency/ad5930.c
index 69e90e9e60e..a4aeee6ffdf 100644
--- a/drivers/staging/iio/frequency/ad5930.c
+++ b/drivers/staging/iio/frequency/ad5930.c
@@ -94,11 +94,9 @@ static int ad5930_probe(struct spi_device *spi)
struct iio_dev *idev;
int ret = 0;
- idev = iio_device_alloc(sizeof(*st));
- if (idev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ idev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (!idev)
+ return -ENOMEM;
spi_set_drvdata(spi, idev);
st = iio_priv(idev);
@@ -110,24 +108,18 @@ static int ad5930_probe(struct spi_device *spi)
ret = iio_device_register(idev);
if (ret)
- goto error_free_dev;
+ return ret;
spi->max_speed_hz = 2000000;
spi->mode = SPI_MODE_3;
spi->bits_per_word = 16;
spi_setup(spi);
return 0;
-
-error_free_dev:
- iio_device_free(idev);
-error_ret:
- return ret;
}
static int ad5930_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
- iio_device_free(spi_get_drvdata(spi));
return 0;
}
diff --git a/drivers/staging/iio/frequency/ad9832.c b/drivers/staging/iio/frequency/ad9832.c
index 4e18380c514..c7d0307c8e7 100644
--- a/drivers/staging/iio/frequency/ad9832.c
+++ b/drivers/staging/iio/frequency/ad9832.c
@@ -81,9 +81,9 @@ static ssize_t ad9832_write(struct device *dev,
struct ad9832_state *st = iio_priv(indio_dev);
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
int ret;
- long val;
+ unsigned long val;
- ret = strict_strtoul(buf, 10, &val);
+ ret = kstrtoul(buf, 10, &val);
if (ret)
goto error_ret;
@@ -214,14 +214,14 @@ static int ad9832_probe(struct spi_device *spi)
return -ENODEV;
}
- reg = regulator_get(&spi->dev, "vcc");
+ reg = devm_regulator_get(&spi->dev, "vcc");
if (!IS_ERR(reg)) {
ret = regulator_enable(reg);
if (ret)
- goto error_put_reg;
+ return ret;
}
- indio_dev = iio_device_alloc(sizeof(*st));
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL) {
ret = -ENOMEM;
goto error_disable_reg;
@@ -279,47 +279,42 @@ static int ad9832_probe(struct spi_device *spi)
ret = spi_sync(st->spi, &st->msg);
if (ret) {
dev_err(&spi->dev, "device init failed\n");
- goto error_free_device;
+ goto error_disable_reg;
}
ret = ad9832_write_frequency(st, AD9832_FREQ0HM, pdata->freq0);
if (ret)
- goto error_free_device;
+ goto error_disable_reg;
ret = ad9832_write_frequency(st, AD9832_FREQ1HM, pdata->freq1);
if (ret)
- goto error_free_device;
+ goto error_disable_reg;
ret = ad9832_write_phase(st, AD9832_PHASE0H, pdata->phase0);
if (ret)
- goto error_free_device;
+ goto error_disable_reg;
ret = ad9832_write_phase(st, AD9832_PHASE1H, pdata->phase1);
if (ret)
- goto error_free_device;
+ goto error_disable_reg;
ret = ad9832_write_phase(st, AD9832_PHASE2H, pdata->phase2);
if (ret)
- goto error_free_device;
+ goto error_disable_reg;
ret = ad9832_write_phase(st, AD9832_PHASE3H, pdata->phase3);
if (ret)
- goto error_free_device;
+ goto error_disable_reg;
ret = iio_device_register(indio_dev);
if (ret)
- goto error_free_device;
+ goto error_disable_reg;
return 0;
-error_free_device:
- iio_device_free(indio_dev);
error_disable_reg:
if (!IS_ERR(reg))
regulator_disable(reg);
-error_put_reg:
- if (!IS_ERR(reg))
- regulator_put(reg);
return ret;
}
@@ -330,11 +325,8 @@ static int ad9832_remove(struct spi_device *spi)
struct ad9832_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
- if (!IS_ERR(st->reg)) {
+ if (!IS_ERR(st->reg))
regulator_disable(st->reg);
- regulator_put(st->reg);
- }
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/frequency/ad9832.h b/drivers/staging/iio/frequency/ad9832.h
index c5b701f8aab..386f4dc8c9a 100644
--- a/drivers/staging/iio/frequency/ad9832.h
+++ b/drivers/staging/iio/frequency/ad9832.h
@@ -92,9 +92,9 @@ struct ad9832_state {
* transfer buffers to live in their own cache lines.
*/
union {
- unsigned short freq_data[4]____cacheline_aligned;
- unsigned short phase_data[2];
- unsigned short data;
+ __be16 freq_data[4]____cacheline_aligned;
+ __be16 phase_data[2];
+ __be16 data;
};
};
diff --git a/drivers/staging/iio/frequency/ad9834.c b/drivers/staging/iio/frequency/ad9834.c
index 5cba3c01f41..86cda617609 100644
--- a/drivers/staging/iio/frequency/ad9834.c
+++ b/drivers/staging/iio/frequency/ad9834.c
@@ -70,9 +70,9 @@ static ssize_t ad9834_write(struct device *dev,
struct ad9834_state *st = iio_priv(indio_dev);
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
int ret;
- long val;
+ unsigned long val;
- ret = strict_strtoul(buf, 10, &val);
+ ret = kstrtoul(buf, 10, &val);
if (ret)
goto error_ret;
@@ -327,14 +327,14 @@ static int ad9834_probe(struct spi_device *spi)
return -ENODEV;
}
- reg = regulator_get(&spi->dev, "vcc");
+ reg = devm_regulator_get(&spi->dev, "vcc");
if (!IS_ERR(reg)) {
ret = regulator_enable(reg);
if (ret)
- goto error_put_reg;
+ return ret;
}
- indio_dev = iio_device_alloc(sizeof(*st));
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL) {
ret = -ENOMEM;
goto error_disable_reg;
@@ -388,39 +388,35 @@ static int ad9834_probe(struct spi_device *spi)
ret = spi_sync(st->spi, &st->msg);
if (ret) {
dev_err(&spi->dev, "device init failed\n");
- goto error_free_device;
+ goto error_disable_reg;
}
ret = ad9834_write_frequency(st, AD9834_REG_FREQ0, pdata->freq0);
if (ret)
- goto error_free_device;
+ goto error_disable_reg;
ret = ad9834_write_frequency(st, AD9834_REG_FREQ1, pdata->freq1);
if (ret)
- goto error_free_device;
+ goto error_disable_reg;
ret = ad9834_write_phase(st, AD9834_REG_PHASE0, pdata->phase0);
if (ret)
- goto error_free_device;
+ goto error_disable_reg;
ret = ad9834_write_phase(st, AD9834_REG_PHASE1, pdata->phase1);
if (ret)
- goto error_free_device;
+ goto error_disable_reg;
ret = iio_device_register(indio_dev);
if (ret)
- goto error_free_device;
+ goto error_disable_reg;
return 0;
-error_free_device:
- iio_device_free(indio_dev);
error_disable_reg:
if (!IS_ERR(reg))
regulator_disable(reg);
-error_put_reg:
- if (!IS_ERR(reg))
- regulator_put(reg);
+
return ret;
}
@@ -430,11 +426,8 @@ static int ad9834_remove(struct spi_device *spi)
struct ad9834_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
- if (!IS_ERR(st->reg)) {
+ if (!IS_ERR(st->reg))
regulator_disable(st->reg);
- regulator_put(st->reg);
- }
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/frequency/ad9834.h b/drivers/staging/iio/frequency/ad9834.h
index ed5ed8d0007..8ca6e52bae6 100644
--- a/drivers/staging/iio/frequency/ad9834.h
+++ b/drivers/staging/iio/frequency/ad9834.h
@@ -65,8 +65,8 @@ struct ad9834_state {
* DMA (thus cache coherency maintenance) requires the
* transfer buffers to live in their own cache lines.
*/
- unsigned short data ____cacheline_aligned;
- unsigned short freq_data[2] ;
+ __be16 data ____cacheline_aligned;
+ __be16 freq_data[2];
};
diff --git a/drivers/staging/iio/frequency/ad9850.c b/drivers/staging/iio/frequency/ad9850.c
index 01a8a93031f..af877ff680e 100644
--- a/drivers/staging/iio/frequency/ad9850.c
+++ b/drivers/staging/iio/frequency/ad9850.c
@@ -80,11 +80,9 @@ static int ad9850_probe(struct spi_device *spi)
struct iio_dev *idev;
int ret = 0;
- idev = iio_device_alloc(sizeof(*st));
- if (idev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ idev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (!idev)
+ return -ENOMEM;
spi_set_drvdata(spi, idev);
st = iio_priv(idev);
mutex_init(&st->lock);
@@ -96,24 +94,18 @@ static int ad9850_probe(struct spi_device *spi)
ret = iio_device_register(idev);
if (ret)
- goto error_free_dev;
+ return ret;
spi->max_speed_hz = 2000000;
spi->mode = SPI_MODE_3;
spi->bits_per_word = 16;
spi_setup(spi);
return 0;
-
-error_free_dev:
- iio_device_free(idev);
-error_ret:
- return ret;
}
static int ad9850_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
- iio_device_free(spi_get_drvdata(spi));
return 0;
}
diff --git a/drivers/staging/iio/frequency/ad9852.c b/drivers/staging/iio/frequency/ad9852.c
index 1344031232b..11e4367375d 100644
--- a/drivers/staging/iio/frequency/ad9852.c
+++ b/drivers/staging/iio/frequency/ad9852.c
@@ -67,7 +67,6 @@ static ssize_t ad9852_set_parameter(struct device *dev,
const char *buf,
size_t len)
{
- struct spi_message msg;
struct spi_transfer xfer;
int ret;
struct ad9852_config *config = (struct ad9852_config *)buf;
@@ -78,99 +77,77 @@ static ssize_t ad9852_set_parameter(struct device *dev,
xfer.tx_buf = &config->phajst0[0];
mutex_lock(&st->lock);
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
xfer.len = 3;
xfer.tx_buf = &config->phajst1[0];
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
xfer.len = 6;
xfer.tx_buf = &config->fretun1[0];
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
xfer.len = 6;
xfer.tx_buf = &config->fretun2[0];
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
xfer.len = 6;
xfer.tx_buf = &config->dltafre[0];
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
xfer.len = 5;
xfer.tx_buf = &config->updtclk[0];
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
xfer.len = 4;
xfer.tx_buf = &config->ramprat[0];
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
xfer.len = 5;
xfer.tx_buf = &config->control[0];
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
xfer.len = 3;
xfer.tx_buf = &config->outpskm[0];
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
xfer.len = 2;
xfer.tx_buf = &config->outpskr[0];
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
xfer.len = 3;
xfer.tx_buf = &config->daccntl[0];
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
error_ret:
@@ -229,11 +206,9 @@ static int ad9852_probe(struct spi_device *spi)
struct iio_dev *idev;
int ret = 0;
- idev = iio_device_alloc(sizeof(*st));
- if (idev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ idev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (!idev)
+ return -ENOMEM;
st = iio_priv(idev);
spi_set_drvdata(spi, idev);
mutex_init(&st->lock);
@@ -245,7 +220,7 @@ static int ad9852_probe(struct spi_device *spi)
ret = iio_device_register(idev);
if (ret)
- goto error_free_dev;
+ return ret;
spi->max_speed_hz = 2000000;
spi->mode = SPI_MODE_3;
spi->bits_per_word = 8;
@@ -253,18 +228,11 @@ static int ad9852_probe(struct spi_device *spi)
ad9852_init(st);
return 0;
-
-error_free_dev:
- iio_device_free(idev);
-
-error_ret:
- return ret;
}
static int ad9852_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
- iio_device_free(spi_get_drvdata(spi));
return 0;
}
diff --git a/drivers/staging/iio/frequency/ad9910.c b/drivers/staging/iio/frequency/ad9910.c
index e48f874c1fc..755e0482681 100644
--- a/drivers/staging/iio/frequency/ad9910.c
+++ b/drivers/staging/iio/frequency/ad9910.c
@@ -119,7 +119,6 @@ static ssize_t ad9910_set_parameter(struct device *dev,
const char *buf,
size_t len)
{
- struct spi_message msg;
struct spi_transfer xfer;
int ret;
struct ad9910_config *config = (struct ad9910_config *)buf;
@@ -130,152 +129,118 @@ static ssize_t ad9910_set_parameter(struct device *dev,
xfer.tx_buf = &config->auxdac[0];
mutex_lock(&st->lock);
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
xfer.len = 5;
xfer.tx_buf = &config->ioupd[0];
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
xfer.len = 5;
xfer.tx_buf = &config->ftw[0];
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
xfer.len = 3;
xfer.tx_buf = &config->pow[0];
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
xfer.len = 5;
xfer.tx_buf = &config->asf[0];
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
xfer.len = 5;
xfer.tx_buf = &config->multc[0];
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
xfer.len = 9;
xfer.tx_buf = &config->dig_rampl[0];
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
xfer.len = 9;
xfer.tx_buf = &config->dig_ramps[0];
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
xfer.len = 5;
xfer.tx_buf = &config->dig_rampr[0];
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
xfer.len = 9;
xfer.tx_buf = &config->sin_tonep0[0];
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
xfer.len = 9;
xfer.tx_buf = &config->sin_tonep1[0];
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
xfer.len = 9;
xfer.tx_buf = &config->sin_tonep2[0];
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
xfer.len = 9;
xfer.tx_buf = &config->sin_tonep3[0];
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
xfer.len = 9;
xfer.tx_buf = &config->sin_tonep4[0];
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
xfer.len = 9;
xfer.tx_buf = &config->sin_tonep5[0];
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
xfer.len = 9;
xfer.tx_buf = &config->sin_tonep6[0];
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
xfer.len = 9;
xfer.tx_buf = &config->sin_tonep7[0];
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
error_ret:
@@ -288,7 +253,6 @@ static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9910_set_parameter, 0);
static void ad9910_init(struct ad9910_state *st)
{
- struct spi_message msg;
struct spi_transfer xfer;
int ret;
u8 cfr[5];
@@ -304,9 +268,7 @@ static void ad9910_init(struct ad9910_state *st)
xfer.len = 5;
xfer.tx_buf = &cfr;
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
@@ -319,9 +281,7 @@ static void ad9910_init(struct ad9910_state *st)
xfer.len = 5;
xfer.tx_buf = &cfr;
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
@@ -334,9 +294,7 @@ static void ad9910_init(struct ad9910_state *st)
xfer.len = 5;
xfer.tx_buf = &cfr;
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
@@ -367,11 +325,9 @@ static int ad9910_probe(struct spi_device *spi)
struct iio_dev *idev;
int ret = 0;
- idev = iio_device_alloc(sizeof(*st));
- if (idev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ idev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (!idev)
+ return -ENOMEM;
spi_set_drvdata(spi, idev);
st = iio_priv(idev);
mutex_init(&st->lock);
@@ -383,24 +339,18 @@ static int ad9910_probe(struct spi_device *spi)
ret = iio_device_register(idev);
if (ret)
- goto error_free_dev;
+ return ret;
spi->max_speed_hz = 2000000;
spi->mode = SPI_MODE_3;
spi->bits_per_word = 8;
spi_setup(spi);
ad9910_init(st);
return 0;
-
-error_free_dev:
- iio_device_free(idev);
-error_ret:
- return ret;
}
static int ad9910_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
- iio_device_free(spi_get_drvdata(spi));
return 0;
}
diff --git a/drivers/staging/iio/frequency/ad9951.c b/drivers/staging/iio/frequency/ad9951.c
index 8234e3c915c..5e8990a0210 100644
--- a/drivers/staging/iio/frequency/ad9951.c
+++ b/drivers/staging/iio/frequency/ad9951.c
@@ -60,7 +60,6 @@ static ssize_t ad9951_set_parameter(struct device *dev,
const char *buf,
size_t len)
{
- struct spi_message msg;
struct spi_transfer xfer;
int ret;
struct ad9951_config *config = (struct ad9951_config *)buf;
@@ -71,36 +70,28 @@ static ssize_t ad9951_set_parameter(struct device *dev,
xfer.tx_buf = &config->asf[0];
mutex_lock(&st->lock);
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
xfer.len = 2;
xfer.tx_buf = &config->arr[0];
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
xfer.len = 5;
xfer.tx_buf = &config->ftw0[0];
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
xfer.len = 3;
xfer.tx_buf = &config->ftw1[0];
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
error_ret:
@@ -113,7 +104,6 @@ static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9951_set_parameter, 0);
static void ad9951_init(struct ad9951_state *st)
{
- struct spi_message msg;
struct spi_transfer xfer;
int ret;
u8 cfr[5];
@@ -129,9 +119,7 @@ static void ad9951_init(struct ad9951_state *st)
xfer.len = 5;
xfer.tx_buf = &cfr;
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
@@ -143,9 +131,7 @@ static void ad9951_init(struct ad9951_state *st)
xfer.len = 4;
xfer.tx_buf = &cfr;
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
- ret = spi_sync(st->sdev, &msg);
+ ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret)
goto error_ret;
@@ -176,11 +162,9 @@ static int ad9951_probe(struct spi_device *spi)
struct iio_dev *idev;
int ret = 0;
- idev = iio_device_alloc(sizeof(*st));
- if (idev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ idev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (!idev)
+ return -ENOMEM;
spi_set_drvdata(spi, idev);
st = iio_priv(idev);
mutex_init(&st->lock);
@@ -193,25 +177,18 @@ static int ad9951_probe(struct spi_device *spi)
ret = iio_device_register(idev);
if (ret)
- goto error_free_dev;
+ return ret;
spi->max_speed_hz = 2000000;
spi->mode = SPI_MODE_3;
spi->bits_per_word = 8;
spi_setup(spi);
ad9951_init(st);
return 0;
-
-error_free_dev:
- iio_device_free(idev);
-
-error_ret:
- return ret;
}
static int ad9951_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
- iio_device_free(spi_get_drvdata(spi));
return 0;
}
diff --git a/drivers/staging/iio/gyro/Kconfig b/drivers/staging/iio/gyro/Kconfig
index b4333715536..88b199bb292 100644
--- a/drivers/staging/iio/gyro/Kconfig
+++ b/drivers/staging/iio/gyro/Kconfig
@@ -10,16 +10,4 @@ config ADIS16060
Say yes here to build support for Analog Devices adis16060 wide bandwidth
yaw rate gyroscope with SPI.
-config ADIS16260
- tristate "Analog Devices ADIS16260 Digital Gyroscope Sensor SPI driver"
- depends on SPI
- select IIO_ADIS_LIB
- select IIO_ADIS_LIB_BUFFER if IIO_BUFFER
- help
- Say yes here to build support for Analog Devices ADIS16260 ADIS16265
- ADIS16250 ADIS16255 and ADIS16251 programmable digital gyroscope sensors.
-
- This driver can also be built as a module. If so, the module
- will be called adis16260.
-
endmenu
diff --git a/drivers/staging/iio/gyro/Makefile b/drivers/staging/iio/gyro/Makefile
index 975f95b141d..cf22d6d55e2 100644
--- a/drivers/staging/iio/gyro/Makefile
+++ b/drivers/staging/iio/gyro/Makefile
@@ -4,6 +4,3 @@
adis16060-y := adis16060_core.o
obj-$(CONFIG_ADIS16060) += adis16060.o
-
-adis16260-y := adis16260_core.o
-obj-$(CONFIG_ADIS16260) += adis16260.o
diff --git a/drivers/staging/iio/gyro/adis16060_core.c b/drivers/staging/iio/gyro/adis16060_core.c
index c67d3a832ae..d5d395c2e3e 100644
--- a/drivers/staging/iio/gyro/adis16060_core.c
+++ b/drivers/staging/iio/gyro/adis16060_core.c
@@ -151,11 +151,9 @@ static int adis16060_r_probe(struct spi_device *spi)
struct iio_dev *indio_dev;
/* setup the industrialio driver allocated elements */
- indio_dev = iio_device_alloc(sizeof(*st));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (!indio_dev)
+ return -ENOMEM;
/* this is only used for removal purposes */
spi_set_drvdata(spi, indio_dev);
st = iio_priv(indio_dev);
@@ -169,26 +167,12 @@ static int adis16060_r_probe(struct spi_device *spi)
indio_dev->channels = adis16060_channels;
indio_dev->num_channels = ARRAY_SIZE(adis16060_channels);
- ret = iio_device_register(indio_dev);
+ ret = devm_iio_device_register(&spi->dev, indio_dev);
if (ret)
- goto error_free_dev;
+ return ret;
adis16060_iio_dev = indio_dev;
return 0;
-
-error_free_dev:
- iio_device_free(indio_dev);
-error_ret:
- return ret;
-}
-
-/* fixme, confirm ordering in this function */
-static int adis16060_r_remove(struct spi_device *spi)
-{
- iio_device_unregister(spi_get_drvdata(spi));
- iio_device_free(spi_get_drvdata(spi));
-
- return 0;
}
static int adis16060_w_probe(struct spi_device *spi)
@@ -220,7 +204,6 @@ static struct spi_driver adis16060_r_driver = {
.owner = THIS_MODULE,
},
.probe = adis16060_r_probe,
- .remove = adis16060_r_remove,
};
static struct spi_driver adis16060_w_driver = {
diff --git a/drivers/staging/iio/gyro/adis16260.h b/drivers/staging/iio/gyro/adis16260.h
deleted file mode 100644
index df3c0b7e954..00000000000
--- a/drivers/staging/iio/gyro/adis16260.h
+++ /dev/null
@@ -1,98 +0,0 @@
-#ifndef SPI_ADIS16260_H_
-#define SPI_ADIS16260_H_
-
-#include "adis16260_platform_data.h"
-#include <linux/iio/imu/adis.h>
-
-#define ADIS16260_STARTUP_DELAY 220 /* ms */
-
-#define ADIS16260_FLASH_CNT 0x00 /* Flash memory write count */
-#define ADIS16260_SUPPLY_OUT 0x02 /* Power supply measurement */
-#define ADIS16260_GYRO_OUT 0x04 /* X-axis gyroscope output */
-#define ADIS16260_AUX_ADC 0x0A /* analog input channel measurement */
-#define ADIS16260_TEMP_OUT 0x0C /* internal temperature measurement */
-#define ADIS16260_ANGL_OUT 0x0E /* angle displacement */
-#define ADIS16260_GYRO_OFF 0x14 /* Calibration, offset/bias adjustment */
-#define ADIS16260_GYRO_SCALE 0x16 /* Calibration, scale adjustment */
-#define ADIS16260_ALM_MAG1 0x20 /* Alarm 1 magnitude/polarity setting */
-#define ADIS16260_ALM_MAG2 0x22 /* Alarm 2 magnitude/polarity setting */
-#define ADIS16260_ALM_SMPL1 0x24 /* Alarm 1 dynamic rate of change setting */
-#define ADIS16260_ALM_SMPL2 0x26 /* Alarm 2 dynamic rate of change setting */
-#define ADIS16260_ALM_CTRL 0x28 /* Alarm control */
-#define ADIS16260_AUX_DAC 0x30 /* Auxiliary DAC data */
-#define ADIS16260_GPIO_CTRL 0x32 /* Control, digital I/O line */
-#define ADIS16260_MSC_CTRL 0x34 /* Control, data ready, self-test settings */
-#define ADIS16260_SMPL_PRD 0x36 /* Control, internal sample rate */
-#define ADIS16260_SENS_AVG 0x38 /* Control, dynamic range, filtering */
-#define ADIS16260_SLP_CNT 0x3A /* Control, sleep mode initiation */
-#define ADIS16260_DIAG_STAT 0x3C /* Diagnostic, error flags */
-#define ADIS16260_GLOB_CMD 0x3E /* Control, global commands */
-#define ADIS16260_LOT_ID1 0x52 /* Lot Identification Code 1 */
-#define ADIS16260_LOT_ID2 0x54 /* Lot Identification Code 2 */
-#define ADIS16260_PROD_ID 0x56 /* Product identifier;
- * convert to decimal = 16,265/16,260 */
-#define ADIS16260_SERIAL_NUM 0x58 /* Serial number */
-
-#define ADIS16260_ERROR_ACTIVE (1<<14)
-#define ADIS16260_NEW_DATA (1<<15)
-
-/* MSC_CTRL */
-#define ADIS16260_MSC_CTRL_MEM_TEST (1<<11)
-/* Internal self-test enable */
-#define ADIS16260_MSC_CTRL_INT_SELF_TEST (1<<10)
-#define ADIS16260_MSC_CTRL_NEG_SELF_TEST (1<<9)
-#define ADIS16260_MSC_CTRL_POS_SELF_TEST (1<<8)
-#define ADIS16260_MSC_CTRL_DATA_RDY_EN (1<<2)
-#define ADIS16260_MSC_CTRL_DATA_RDY_POL_HIGH (1<<1)
-#define ADIS16260_MSC_CTRL_DATA_RDY_DIO2 (1<<0)
-
-/* SMPL_PRD */
-/* Time base (tB): 0 = 1.953 ms, 1 = 60.54 ms */
-#define ADIS16260_SMPL_PRD_TIME_BASE (1<<7)
-#define ADIS16260_SMPL_PRD_DIV_MASK 0x7F
-
-/* SLP_CNT */
-#define ADIS16260_SLP_CNT_POWER_OFF 0x80
-
-/* DIAG_STAT */
-#define ADIS16260_DIAG_STAT_ALARM2 (1<<9)
-#define ADIS16260_DIAG_STAT_ALARM1 (1<<8)
-#define ADIS16260_DIAG_STAT_FLASH_CHK_BIT 6
-#define ADIS16260_DIAG_STAT_SELF_TEST_BIT 5
-#define ADIS16260_DIAG_STAT_OVERFLOW_BIT 4
-#define ADIS16260_DIAG_STAT_SPI_FAIL_BIT 3
-#define ADIS16260_DIAG_STAT_FLASH_UPT_BIT 2
-#define ADIS16260_DIAG_STAT_POWER_HIGH_BIT 1
-#define ADIS16260_DIAG_STAT_POWER_LOW_BIT 0
-
-/* GLOB_CMD */
-#define ADIS16260_GLOB_CMD_SW_RESET (1<<7)
-#define ADIS16260_GLOB_CMD_FLASH_UPD (1<<3)
-#define ADIS16260_GLOB_CMD_DAC_LATCH (1<<2)
-#define ADIS16260_GLOB_CMD_FAC_CALIB (1<<1)
-#define ADIS16260_GLOB_CMD_AUTO_NULL (1<<0)
-
-#define ADIS16260_SPI_SLOW (u32)(300 * 1000)
-#define ADIS16260_SPI_BURST (u32)(1000 * 1000)
-#define ADIS16260_SPI_FAST (u32)(2000 * 1000)
-
-/**
- * struct adis16260_state - device instance specific data
- * @negate: negate the scale parameter
- **/
-struct adis16260_state {
- unsigned negate:1;
- struct adis adis;
-};
-
-/* At the moment triggers are only used for ring buffer
- * filling. This may change!
- */
-
-#define ADIS16260_SCAN_GYRO 0
-#define ADIS16260_SCAN_SUPPLY 1
-#define ADIS16260_SCAN_AUX_ADC 2
-#define ADIS16260_SCAN_TEMP 3
-#define ADIS16260_SCAN_ANGL 4
-
-#endif /* SPI_ADIS16260_H_ */
diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c
deleted file mode 100644
index 620d63fd099..00000000000
--- a/drivers/staging/iio/gyro/adis16260_core.c
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- * ADIS16260/ADIS16265 Programmable Digital Gyroscope Sensor Driver
- *
- * Copyright 2010 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/delay.h>
-#include <linux/mutex.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/list.h>
-#include <linux/module.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-#include <linux/iio/buffer.h>
-
-#include "adis16260.h"
-
-static ssize_t adis16260_read_frequency_available(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct adis16260_state *st = iio_priv(indio_dev);
- if (spi_get_device_id(st->adis.spi)->driver_data)
- return sprintf(buf, "%s\n", "0.129 ~ 256");
- else
- return sprintf(buf, "%s\n", "256 2048");
-}
-
-static ssize_t adis16260_read_frequency(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct adis16260_state *st = iio_priv(indio_dev);
- int ret, len = 0;
- u16 t;
- int sps;
- ret = adis_read_reg_16(&st->adis, ADIS16260_SMPL_PRD, &t);
- if (ret)
- return ret;
-
- if (spi_get_device_id(st->adis.spi)->driver_data) /* If an adis16251 */
- sps = (t & ADIS16260_SMPL_PRD_TIME_BASE) ? 8 : 256;
- else
- sps = (t & ADIS16260_SMPL_PRD_TIME_BASE) ? 66 : 2048;
- sps /= (t & ADIS16260_SMPL_PRD_DIV_MASK) + 1;
- len = sprintf(buf, "%d SPS\n", sps);
- return len;
-}
-
-static ssize_t adis16260_write_frequency(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct adis16260_state *st = iio_priv(indio_dev);
- long val;
- int ret;
- u8 t;
-
- ret = strict_strtol(buf, 10, &val);
- if (ret)
- return ret;
- if (val == 0)
- return -EINVAL;
-
- mutex_lock(&indio_dev->mlock);
- if (spi_get_device_id(st->adis.spi)->driver_data) {
- t = (256 / val);
- if (t > 0)
- t--;
- t &= ADIS16260_SMPL_PRD_DIV_MASK;
- } else {
- t = (2048 / val);
- if (t > 0)
- t--;
- t &= ADIS16260_SMPL_PRD_DIV_MASK;
- }
- if ((t & ADIS16260_SMPL_PRD_DIV_MASK) >= 0x0A)
- st->adis.spi->max_speed_hz = ADIS16260_SPI_SLOW;
- else
- st->adis.spi->max_speed_hz = ADIS16260_SPI_FAST;
- ret = adis_write_reg_8(&st->adis,
- ADIS16260_SMPL_PRD,
- t);
-
- mutex_unlock(&indio_dev->mlock);
-
- return ret ? ret : len;
-}
-
-/* Power down the device */
-static int adis16260_stop_device(struct iio_dev *indio_dev)
-{
- struct adis16260_state *st = iio_priv(indio_dev);
- int ret;
- u16 val = ADIS16260_SLP_CNT_POWER_OFF;
-
- ret = adis_write_reg_16(&st->adis, ADIS16260_SLP_CNT, val);
- if (ret)
- dev_err(&indio_dev->dev, "problem with turning device off: SLP_CNT");
-
- return ret;
-}
-
-static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
- adis16260_read_frequency,
- adis16260_write_frequency);
-
-static IIO_DEVICE_ATTR(sampling_frequency_available,
- S_IRUGO, adis16260_read_frequency_available, NULL, 0);
-
-#define ADIS16260_GYRO_CHANNEL_SET(axis, mod) \
-struct iio_chan_spec adis16260_channels_##axis[] = { \
- ADIS_GYRO_CHAN(mod, ADIS16260_GYRO_OUT, ADIS16260_SCAN_GYRO, \
- BIT(IIO_CHAN_INFO_CALIBBIAS) | \
- BIT(IIO_CHAN_INFO_CALIBSCALE), 14), \
- ADIS_INCLI_CHAN(mod, ADIS16260_ANGL_OUT, ADIS16260_SCAN_ANGL, 0, 14), \
- ADIS_TEMP_CHAN(ADIS16260_TEMP_OUT, ADIS16260_SCAN_TEMP, 12), \
- ADIS_SUPPLY_CHAN(ADIS16260_SUPPLY_OUT, ADIS16260_SCAN_SUPPLY, 12), \
- ADIS_AUX_ADC_CHAN(ADIS16260_AUX_ADC, ADIS16260_SCAN_AUX_ADC, 12), \
- IIO_CHAN_SOFT_TIMESTAMP(5), \
-}
-
-static const ADIS16260_GYRO_CHANNEL_SET(x, X);
-static const ADIS16260_GYRO_CHANNEL_SET(y, Y);
-static const ADIS16260_GYRO_CHANNEL_SET(z, Z);
-
-static const u8 adis16260_addresses[][2] = {
- [ADIS16260_SCAN_GYRO] = { ADIS16260_GYRO_OFF, ADIS16260_GYRO_SCALE },
-};
-
-static int adis16260_read_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int *val, int *val2,
- long mask)
-{
- struct adis16260_state *st = iio_priv(indio_dev);
- int ret;
- int bits;
- u8 addr;
- s16 val16;
-
- switch (mask) {
- case IIO_CHAN_INFO_RAW:
- return adis_single_conversion(indio_dev, chan,
- ADIS16260_ERROR_ACTIVE, val);
- case IIO_CHAN_INFO_SCALE:
- switch (chan->type) {
- case IIO_ANGL_VEL:
- *val = 0;
- if (spi_get_device_id(st->adis.spi)->driver_data) {
- /* 0.01832 degree / sec */
- *val2 = IIO_DEGREE_TO_RAD(18320);
- } else {
- /* 0.07326 degree / sec */
- *val2 = IIO_DEGREE_TO_RAD(73260);
- }
- return IIO_VAL_INT_PLUS_MICRO;
- case IIO_VOLTAGE:
- if (chan->channel == 0) {
- *val = 1;
- *val2 = 831500; /* 1.8315 mV */
- } else {
- *val = 0;
- *val2 = 610500; /* 610.5 uV */
- }
- return IIO_VAL_INT_PLUS_MICRO;
- case IIO_TEMP:
- *val = 145;
- *val2 = 300000; /* 0.1453 C */
- return IIO_VAL_INT_PLUS_MICRO;
- default:
- return -EINVAL;
- }
- break;
- case IIO_CHAN_INFO_OFFSET:
- *val = 250000 / 1453; /* 25 C = 0x00 */
- return IIO_VAL_INT;
- case IIO_CHAN_INFO_CALIBBIAS:
- switch (chan->type) {
- case IIO_ANGL_VEL:
- bits = 12;
- break;
- default:
- return -EINVAL;
- }
- mutex_lock(&indio_dev->mlock);
- addr = adis16260_addresses[chan->scan_index][0];
- ret = adis_read_reg_16(&st->adis, addr, &val16);
- if (ret) {
- mutex_unlock(&indio_dev->mlock);
- return ret;
- }
- val16 &= (1 << bits) - 1;
- val16 = (s16)(val16 << (16 - bits)) >> (16 - bits);
- *val = val16;
- mutex_unlock(&indio_dev->mlock);
- return IIO_VAL_INT;
- case IIO_CHAN_INFO_CALIBSCALE:
- switch (chan->type) {
- case IIO_ANGL_VEL:
- bits = 12;
- break;
- default:
- return -EINVAL;
- }
- mutex_lock(&indio_dev->mlock);
- addr = adis16260_addresses[chan->scan_index][1];
- ret = adis_read_reg_16(&st->adis, addr, &val16);
- if (ret) {
- mutex_unlock(&indio_dev->mlock);
- return ret;
- }
- *val = (1 << bits) - 1;
- mutex_unlock(&indio_dev->mlock);
- return IIO_VAL_INT;
- }
- return -EINVAL;
-}
-
-static int adis16260_write_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int val,
- int val2,
- long mask)
-{
- struct adis16260_state *st = iio_priv(indio_dev);
- int bits = 12;
- s16 val16;
- u8 addr;
- switch (mask) {
- case IIO_CHAN_INFO_CALIBBIAS:
- val16 = val & ((1 << bits) - 1);
- addr = adis16260_addresses[chan->scan_index][0];
- return adis_write_reg_16(&st->adis, addr, val16);
- case IIO_CHAN_INFO_CALIBSCALE:
- val16 = val & ((1 << bits) - 1);
- addr = adis16260_addresses[chan->scan_index][1];
- return adis_write_reg_16(&st->adis, addr, val16);
- }
- return -EINVAL;
-}
-
-static struct attribute *adis16260_attributes[] = {
- &iio_dev_attr_sampling_frequency.dev_attr.attr,
- &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
- NULL
-};
-
-static const struct attribute_group adis16260_attribute_group = {
- .attrs = adis16260_attributes,
-};
-
-static const struct iio_info adis16260_info = {
- .attrs = &adis16260_attribute_group,
- .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[] = {
- [ADIS16260_DIAG_STAT_FLASH_CHK_BIT] = "Flash checksum error",
- [ADIS16260_DIAG_STAT_SELF_TEST_BIT] = "Self test error",
- [ADIS16260_DIAG_STAT_OVERFLOW_BIT] = "Sensor overrange",
- [ADIS16260_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure",
- [ADIS16260_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed",
- [ADIS16260_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 5.25",
- [ADIS16260_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 4.75",
-};
-
-static const struct adis_data adis16260_data = {
- .write_delay = 30,
- .read_delay = 30,
- .msc_ctrl_reg = ADIS16260_MSC_CTRL,
- .glob_cmd_reg = ADIS16260_GLOB_CMD,
- .diag_stat_reg = ADIS16260_DIAG_STAT,
-
- .self_test_mask = ADIS16260_MSC_CTRL_MEM_TEST,
- .startup_delay = ADIS16260_STARTUP_DELAY,
-
- .status_error_msgs = adis1620_status_error_msgs,
- .status_error_mask = BIT(ADIS16260_DIAG_STAT_FLASH_CHK_BIT) |
- BIT(ADIS16260_DIAG_STAT_SELF_TEST_BIT) |
- BIT(ADIS16260_DIAG_STAT_OVERFLOW_BIT) |
- BIT(ADIS16260_DIAG_STAT_SPI_FAIL_BIT) |
- BIT(ADIS16260_DIAG_STAT_FLASH_UPT_BIT) |
- BIT(ADIS16260_DIAG_STAT_POWER_HIGH_BIT) |
- BIT(ADIS16260_DIAG_STAT_POWER_LOW_BIT),
-};
-
-static int adis16260_probe(struct spi_device *spi)
-{
- int ret;
- struct adis16260_platform_data *pd = spi->dev.platform_data;
- struct adis16260_state *st;
- struct iio_dev *indio_dev;
-
- /* setup the industrialio driver allocated elements */
- indio_dev = iio_device_alloc(sizeof(*st));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
- st = iio_priv(indio_dev);
- if (pd)
- st->negate = pd->negate;
- /* this is only used for removal purposes */
- spi_set_drvdata(spi, indio_dev);
-
- indio_dev->name = spi_get_device_id(spi)->name;
- indio_dev->dev.parent = &spi->dev;
- indio_dev->info = &adis16260_info;
- indio_dev->num_channels
- = ARRAY_SIZE(adis16260_channels_x);
- if (pd && pd->direction)
- switch (pd->direction) {
- case 'x':
- indio_dev->channels = adis16260_channels_x;
- break;
- case 'y':
- indio_dev->channels = adis16260_channels_y;
- break;
- case 'z':
- indio_dev->channels = adis16260_channels_z;
- break;
- default:
- return -EINVAL;
- }
- else
- indio_dev->channels = adis16260_channels_x;
- indio_dev->num_channels = ARRAY_SIZE(adis16260_channels_x);
- indio_dev->modes = INDIO_DIRECT_MODE;
-
- ret = adis_init(&st->adis, indio_dev, spi, &adis16260_data);
- if (ret)
- goto error_free_dev;
-
- ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL);
- if (ret)
- goto error_free_dev;
-
- if (indio_dev->buffer) {
- /* Set default scan mode */
- iio_scan_mask_set(indio_dev, indio_dev->buffer,
- ADIS16260_SCAN_SUPPLY);
- iio_scan_mask_set(indio_dev, indio_dev->buffer,
- ADIS16260_SCAN_GYRO);
- iio_scan_mask_set(indio_dev, indio_dev->buffer,
- ADIS16260_SCAN_AUX_ADC);
- iio_scan_mask_set(indio_dev, indio_dev->buffer,
- ADIS16260_SCAN_TEMP);
- iio_scan_mask_set(indio_dev, indio_dev->buffer,
- ADIS16260_SCAN_ANGL);
- }
-
- /* Get the device into a sane initial state */
- ret = adis_initial_startup(&st->adis);
- if (ret)
- goto error_cleanup_buffer_trigger;
- ret = iio_device_register(indio_dev);
- if (ret)
- goto error_cleanup_buffer_trigger;
-
- return 0;
-
-error_cleanup_buffer_trigger:
- adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
-error_free_dev:
- iio_device_free(indio_dev);
-error_ret:
- return ret;
-}
-
-static int adis16260_remove(struct spi_device *spi)
-{
- struct iio_dev *indio_dev = spi_get_drvdata(spi);
- struct adis16260_state *st = iio_priv(indio_dev);
-
- iio_device_unregister(indio_dev);
- adis16260_stop_device(indio_dev);
- adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
- iio_device_free(indio_dev);
-
- return 0;
-}
-
-/*
- * These parts do not need to be differentiated until someone adds
- * support for the on chip filtering.
- */
-static const struct spi_device_id adis16260_id[] = {
- {"adis16260", 0},
- {"adis16265", 0},
- {"adis16250", 0},
- {"adis16255", 0},
- {"adis16251", 1},
- {}
-};
-MODULE_DEVICE_TABLE(spi, adis16260_id);
-
-static struct spi_driver adis16260_driver = {
- .driver = {
- .name = "adis16260",
- .owner = THIS_MODULE,
- },
- .probe = adis16260_probe,
- .remove = adis16260_remove,
- .id_table = adis16260_id,
-};
-module_spi_driver(adis16260_driver);
-
-MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
-MODULE_DESCRIPTION("Analog Devices ADIS16260/5 Digital Gyroscope Sensor");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/gyro/adis16260_platform_data.h b/drivers/staging/iio/gyro/adis16260_platform_data.h
deleted file mode 100644
index 12802e97be9..00000000000
--- a/drivers/staging/iio/gyro/adis16260_platform_data.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * ADIS16260 Programmable Digital Gyroscope Sensor Driver Platform Data
- *
- * Based on adis16255.h Matthia Brugger <m_brugger&web.de>
- *
- * Copyright (C) 2010 Fraunhofer Institute for Integrated Circuits
- *
- * Licensed under the GPL-2 or later.
- */
-
-/**
- * struct adis16260_platform_data - instance specific data
- * @direction: x y or z
- * @negate: flag to indicate value should be inverted.
- **/
-struct adis16260_platform_data {
- char direction;
- unsigned negate:1;
-};
diff --git a/drivers/staging/iio/iio_simple_dummy.c b/drivers/staging/iio/iio_simple_dummy.c
index 0e8e02a3cf5..fd334a03a49 100644
--- a/drivers/staging/iio/iio_simple_dummy.c
+++ b/drivers/staging/iio/iio_simple_dummy.c
@@ -57,6 +57,20 @@ static const struct iio_dummy_accel_calibscale dummy_scales[] = {
{ 733, 13, 0x9 }, /* 733.000013 */
};
+#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
+
+/*
+ * simple event - triggered when value rises above
+ * a threshold
+ */
+static const struct iio_event_spec iio_dummy_event = {
+ .type = IIO_EV_TYPE_THRESH,
+ .dir = IIO_EV_DIR_RISING,
+ .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
+};
+
+#endif
+
/*
* iio_dummy_channels - Description of available channels
*
@@ -90,6 +104,11 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
* when converting to standard units (microvolts)
*/
BIT(IIO_CHAN_INFO_SCALE),
+ /*
+ * sampling_frequency
+ * The frequency in Hz at which the channels are sampled
+ */
+ .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
/* The ordering of elements in the buffer via an enum */
.scan_index = voltage0,
.scan_type = { /* Description of storage in buffer */
@@ -99,12 +118,8 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
.shift = 0, /* zero shift */
},
#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
- /*
- * simple event - triggered when value rises above
- * a threshold
- */
- .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH,
- IIO_EV_DIR_RISING),
+ .event_spec = &iio_dummy_event,
+ .num_event_specs = 1,
#endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
},
/* Differential ADC channel in_voltage1-voltage2_raw etc*/
@@ -130,6 +145,10 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
* input channels of type IIO_VOLTAGE.
*/
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
+ /*
+ * sampling_frequency
+ * The frequency in Hz at which the channels are sampled
+ */
.scan_index = diffvoltage1m2,
.scan_type = { /* Description of storage in buffer */
.sign = 's', /* signed */
@@ -147,6 +166,7 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
.channel2 = 4,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
+ .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
.scan_index = diffvoltage3m4,
.scan_type = {
.sign = 's',
@@ -173,6 +193,7 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
*/
BIT(IIO_CHAN_INFO_CALIBSCALE) |
BIT(IIO_CHAN_INFO_CALIBBIAS),
+ .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
.scan_index = accelx,
.scan_type = { /* Description of storage in buffer */
.sign = 's', /* signed */
@@ -272,6 +293,11 @@ static int iio_dummy_read_raw(struct iio_dev *indio_dev,
*val2 = st->accel_calibscale->val2;
ret = IIO_VAL_INT_PLUS_MICRO;
break;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ *val = 3;
+ *val2 = 33;
+ ret = IIO_VAL_INT_PLUS_NANO;
+ break;
default:
break;
}
@@ -454,7 +480,8 @@ static int iio_dummy_probe(int index)
* buffer, but avoid the output channel being registered by reducing the
* number of channels by 1.
*/
- ret = iio_simple_dummy_configure_buffer(indio_dev, iio_dummy_channels, 5);
+ ret = iio_simple_dummy_configure_buffer(indio_dev,
+ iio_dummy_channels, 5);
if (ret < 0)
goto error_unregister_events;
diff --git a/drivers/staging/iio/iio_simple_dummy.h b/drivers/staging/iio/iio_simple_dummy.h
index c9e8702caca..b126196cdf3 100644
--- a/drivers/staging/iio/iio_simple_dummy.h
+++ b/drivers/staging/iio/iio_simple_dummy.h
@@ -45,19 +45,29 @@ struct iio_dummy_state {
struct iio_dev;
int iio_simple_dummy_read_event_config(struct iio_dev *indio_dev,
- u64 event_code);
+ const struct iio_chan_spec *chan,
+ enum iio_event_type type,
+ enum iio_event_direction dir);
int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
- u64 event_code,
+ const struct iio_chan_spec *chan,
+ enum iio_event_type type,
+ enum iio_event_direction dir,
int state);
int iio_simple_dummy_read_event_value(struct iio_dev *indio_dev,
- u64 event_code,
- int *val);
+ 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);
int iio_simple_dummy_write_event_value(struct iio_dev *indio_dev,
- u64 event_code,
- int val);
+ 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);
int iio_simple_dummy_events_register(struct iio_dev *indio_dev);
int iio_simple_dummy_events_unregister(struct iio_dev *indio_dev);
diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/staging/iio/iio_simple_dummy_buffer.c
index 72f400c3cbc..46c134b2a5d 100644
--- a/drivers/staging/iio/iio_simple_dummy_buffer.c
+++ b/drivers/staging/iio/iio_simple_dummy_buffer.c
@@ -82,11 +82,8 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p)
len += 2;
}
}
- /* Store the timestamp at an 8 byte aligned offset */
- if (indio_dev->scan_timestamp)
- *(s64 *)((u8 *)data + ALIGN(len, sizeof(s64)))
- = iio_get_time_ns();
- iio_push_to_buffers(indio_dev, (u8 *)data);
+
+ iio_push_to_buffers_with_timestamp(indio_dev, data, iio_get_time_ns());
kfree(data);
@@ -102,14 +99,6 @@ done:
static const struct iio_buffer_setup_ops iio_simple_dummy_buffer_setup_ops = {
/*
- * iio_sw_buffer_preenable:
- * Generic function for equal sized ring elements + 64 bit timestamp
- * Assumes that any combination of channels can be enabled.
- * Typically replaced to implement restrictions on what combinations
- * can be captured (hardware scan modes).
- */
- .preenable = &iio_sw_buffer_preenable,
- /*
* iio_triggered_buffer_postenable:
* Generic function that simply attaches the pollfunc to the trigger.
* Replace this to mess with hardware state before we attach the
@@ -138,7 +127,7 @@ int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev,
goto error_ret;
}
- indio_dev->buffer = buffer;
+ iio_device_attach_buffer(indio_dev, buffer);
/* Enable timestamps by default */
buffer->scan_timestamp = true;
diff --git a/drivers/staging/iio/iio_simple_dummy_events.c b/drivers/staging/iio/iio_simple_dummy_events.c
index 317b77465db..812ebd05a7f 100644
--- a/drivers/staging/iio/iio_simple_dummy_events.c
+++ b/drivers/staging/iio/iio_simple_dummy_events.c
@@ -23,13 +23,17 @@
/**
* iio_simple_dummy_read_event_config() - is event enabled?
* @indio_dev: the device instance data
- * @event_code: event code of the event being queried
+ * @chan: channel for the event whose state is being queried
+ * @type: type of the event whose state is being queried
+ * @dir: direction of the vent whose state is being queried
*
* This function would normally query the relevant registers or a cache to
* discover if the event generation is enabled on the device.
*/
int iio_simple_dummy_read_event_config(struct iio_dev *indio_dev,
- u64 event_code)
+ const struct iio_chan_spec *chan,
+ enum iio_event_type type,
+ enum iio_event_direction dir)
{
struct iio_dummy_state *st = iio_priv(indio_dev);
@@ -39,7 +43,9 @@ int iio_simple_dummy_read_event_config(struct iio_dev *indio_dev,
/**
* iio_simple_dummy_write_event_config() - set whether event is enabled
* @indio_dev: the device instance data
- * @event_code: event code of event being enabled/disabled
+ * @chan: channel for the event whose state is being set
+ * @type: type of the event whose state is being set
+ * @dir: direction of the vent whose state is being set
* @state: whether to enable or disable the device.
*
* This function would normally set the relevant registers on the devices
@@ -47,7 +53,9 @@ int iio_simple_dummy_read_event_config(struct iio_dev *indio_dev,
* value.
*/
int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
- u64 event_code,
+ const struct iio_chan_spec *chan,
+ enum iio_event_type type,
+ enum iio_event_direction dir,
int state)
{
struct iio_dummy_state *st = iio_priv(indio_dev);
@@ -56,12 +64,11 @@ int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
* Deliberately over the top code splitting to illustrate
* how this is done when multiple events exist.
*/
- switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
+ switch (chan->type) {
case IIO_VOLTAGE:
- switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+ switch (type) {
case IIO_EV_TYPE_THRESH:
- if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
- IIO_EV_DIR_RISING)
+ if (dir == IIO_EV_DIR_RISING)
st->event_en = state;
else
return -EINVAL;
@@ -79,7 +86,10 @@ int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
/**
* iio_simple_dummy_read_event_value() - get value associated with event
* @indio_dev: device instance specific data
- * @event_code: event code for the event whose value is being queried
+ * @chan: channel for the event whose value is being read
+ * @type: type of the event whose value is being read
+ * @dir: direction of the vent whose value is being read
+ * @info: info type of the event whose value is being read
* @val: value for the event code.
*
* Many devices provide a large set of events of which only a subset may
@@ -89,25 +99,34 @@ int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
* the enabled event is changed.
*/
int iio_simple_dummy_read_event_value(struct iio_dev *indio_dev,
- u64 event_code,
- int *val)
+ 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 iio_dummy_state *st = iio_priv(indio_dev);
*val = st->event_val;
- return 0;
+ return IIO_VAL_INT;
}
/**
* iio_simple_dummy_write_event_value() - set value associate with event
* @indio_dev: device instance specific data
- * @event_code: event code for the event whose value is being set
+ * @chan: channel for the event whose value is being set
+ * @type: type of the event whose value is being set
+ * @dir: direction of the vent whose value is being set
+ * @info: info type of the event whose value is being set
* @val: the value to be set.
*/
int iio_simple_dummy_write_event_value(struct iio_dev *indio_dev,
- u64 event_code,
- int val)
+ 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 iio_dummy_state *st = iio_priv(indio_dev);
diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c
index 6330af656a0..2b96665da8a 100644
--- a/drivers/staging/iio/impedance-analyzer/ad5933.c
+++ b/drivers/staging/iio/impedance-analyzer/ad5933.c
@@ -323,10 +323,10 @@ static ssize_t ad5933_store_frequency(struct device *dev,
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ad5933_state *st = iio_priv(indio_dev);
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
- long val;
+ unsigned long val;
int ret;
- ret = strict_strtoul(buf, 10, &val);
+ ret = kstrtoul(buf, 10, &val);
if (ret)
return ret;
@@ -400,12 +400,12 @@ static ssize_t ad5933_store(struct device *dev,
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ad5933_state *st = iio_priv(indio_dev);
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
- long val;
+ u16 val;
int i, ret = 0;
unsigned short dat;
if (this_attr->address != AD5933_IN_PGA_GAIN) {
- ret = strict_strtol(buf, 10, &val);
+ ret = kstrtou16(buf, 10, &val);
if (ret)
return ret;
}
@@ -434,7 +434,7 @@ static ssize_t ad5933_store(struct device *dev,
ret = ad5933_cmd(st, 0);
break;
case AD5933_OUT_SETTLING_CYCLES:
- val = clamp(val, 0L, 0x7FFL);
+ val = clamp(val, (u16)0, (u16)0x7FF);
st->settling_cycles = val;
/* 2x, 4x handling, see datasheet */
@@ -448,7 +448,7 @@ static ssize_t ad5933_store(struct device *dev,
AD5933_REG_SETTLING_CYCLES, 2, (u8 *)&dat);
break;
case AD5933_FREQ_POINTS:
- val = clamp(val, 0L, 511L);
+ val = clamp(val, (u16)0, (u16)511);
st->freq_points = val;
dat = cpu_to_be16(val);
@@ -574,10 +574,6 @@ static int ad5933_ring_preenable(struct iio_dev *indio_dev)
if (bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
return -EINVAL;
- ret = iio_sw_buffer_preenable(indio_dev);
- if (ret < 0)
- return ret;
-
ret = ad5933_reset(st);
if (ret < 0)
return ret;
@@ -630,10 +626,14 @@ static const struct iio_buffer_setup_ops ad5933_ring_setup_ops = {
static int ad5933_register_ring_funcs_and_init(struct iio_dev *indio_dev)
{
- indio_dev->buffer = iio_kfifo_allocate(indio_dev);
- if (!indio_dev->buffer)
+ struct iio_buffer *buffer;
+
+ buffer = iio_kfifo_allocate(indio_dev);
+ if (!buffer)
return -ENOMEM;
+ iio_device_attach_buffer(indio_dev, buffer);
+
/* Ring buffer functions - here trigger setup related */
indio_dev->setup_ops = &ad5933_ring_setup_ops;
@@ -676,7 +676,7 @@ static void ad5933_work(struct work_struct *work)
} else {
buf[0] = be16_to_cpu(buf[0]);
}
- iio_push_to_buffers(indio_dev, (u8 *)buf);
+ iio_push_to_buffers(indio_dev, buf);
} else {
/* no data available - try again later */
schedule_delayed_work(&st->work, st->poll_time_jiffies);
@@ -703,7 +703,9 @@ static int ad5933_probe(struct i2c_client *client,
int ret, voltage_uv = 0;
struct ad5933_platform_data *pdata = client->dev.platform_data;
struct ad5933_state *st;
- struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
+ struct iio_dev *indio_dev;
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
@@ -716,11 +718,11 @@ static int ad5933_probe(struct i2c_client *client,
else
st->pdata = pdata;
- st->reg = regulator_get(&client->dev, "vcc");
+ st->reg = devm_regulator_get(&client->dev, "vcc");
if (!IS_ERR(st->reg)) {
ret = regulator_enable(st->reg);
if (ret)
- goto error_put_reg;
+ return ret;
voltage_uv = regulator_get_voltage(st->reg);
}
@@ -778,11 +780,6 @@ error_unreg_ring:
error_disable_reg:
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
-error_put_reg:
- if (!IS_ERR(st->reg))
- regulator_put(st->reg);
-
- iio_device_free(indio_dev);
return ret;
}
@@ -795,11 +792,8 @@ static int ad5933_remove(struct i2c_client *client)
iio_device_unregister(indio_dev);
iio_buffer_unregister(indio_dev);
iio_kfifo_free(indio_dev->buffer);
- if (!IS_ERR(st->reg)) {
+ if (!IS_ERR(st->reg))
regulator_disable(st->reg);
- regulator_put(st->reg);
- }
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c
index 82478a59e42..3660a43b5f0 100644
--- a/drivers/staging/iio/light/isl29018.c
+++ b/drivers/staging/iio/light/isl29018.c
@@ -240,7 +240,7 @@ static ssize_t store_range(struct device *dev,
unsigned long lval;
unsigned int new_range;
- if (strict_strtoul(buf, 10, &lval))
+ if (kstrtoul(buf, 10, &lval))
return -EINVAL;
if (!(lval == 1000UL || lval == 4000UL ||
@@ -279,18 +279,18 @@ static ssize_t store_resolution(struct device *dev,
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct isl29018_chip *chip = iio_priv(indio_dev);
int status;
- unsigned long lval;
+ unsigned int val;
unsigned int new_adc_bit;
- if (strict_strtoul(buf, 10, &lval))
+ if (kstrtouint(buf, 10, &val))
return -EINVAL;
- if (!(lval == 4 || lval == 8 || lval == 12 || lval == 16)) {
+ if (!(val == 4 || val == 8 || val == 12 || val == 16)) {
dev_err(dev, "The resolution is not supported\n");
return -EINVAL;
}
mutex_lock(&chip->lock);
- status = isl29018_set_resolution(chip, lval, &new_adc_bit);
+ status = isl29018_set_resolution(chip, val, &new_adc_bit);
if (status < 0) {
mutex_unlock(&chip->lock);
dev_err(dev, "Error in setting resolution\n");
@@ -319,11 +319,11 @@ static ssize_t store_prox_infrared_suppression(struct device *dev,
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct isl29018_chip *chip = iio_priv(indio_dev);
- unsigned long lval;
+ int val;
- if (strict_strtoul(buf, 10, &lval))
+ if (kstrtoint(buf, 10, &val))
return -EINVAL;
- if (!(lval == 0UL || lval == 1UL)) {
+ if (!(val == 0 || val == 1)) {
dev_err(dev, "The mode is not supported\n");
return -EINVAL;
}
@@ -331,7 +331,7 @@ static ssize_t store_prox_infrared_suppression(struct device *dev,
/* get the "proximity scheme" i.e. if the chip does on chip
infrared suppression (1 means perform on chip suppression) */
mutex_lock(&chip->lock);
- chip->prox_scheme = (int)lval;
+ chip->prox_scheme = val;
mutex_unlock(&chip->lock);
return count;
@@ -550,11 +550,10 @@ static int isl29018_probe(struct i2c_client *client,
struct iio_dev *indio_dev;
int err;
- indio_dev = iio_device_alloc(sizeof(*chip));
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
if (indio_dev == NULL) {
dev_err(&client->dev, "iio allocation fails\n");
- err = -ENOMEM;
- goto exit;
+ return -ENOMEM;
}
chip = iio_priv(indio_dev);
@@ -564,6 +563,7 @@ static int isl29018_probe(struct i2c_client *client,
mutex_init(&chip->lock);
chip->lux_scale = 1;
+ chip->lux_uscale = 0;
chip->range = 1000;
chip->adc_bit = 16;
chip->suspended = false;
@@ -572,12 +572,12 @@ static int isl29018_probe(struct i2c_client *client,
if (IS_ERR(chip->regmap)) {
err = PTR_ERR(chip->regmap);
dev_err(chip->dev, "regmap initialization failed: %d\n", err);
- goto exit;
+ return err;
}
err = isl29018_chip_init(chip);
if (err)
- goto exit_iio_free;
+ return err;
indio_dev->info = &isl29108_info;
indio_dev->channels = isl29018_channels;
@@ -585,28 +585,13 @@ static int isl29018_probe(struct i2c_client *client,
indio_dev->name = id->name;
indio_dev->dev.parent = &client->dev;
indio_dev->modes = INDIO_DIRECT_MODE;
- err = iio_device_register(indio_dev);
+ err = devm_iio_device_register(&client->dev, indio_dev);
if (err) {
dev_err(&client->dev, "iio registration fails\n");
- goto exit_iio_free;
+ return err;
}
return 0;
-exit_iio_free:
- iio_device_free(indio_dev);
-exit:
- return err;
-}
-
-static int isl29018_remove(struct i2c_client *client)
-{
- struct iio_dev *indio_dev = i2c_get_clientdata(client);
-
- dev_dbg(&client->dev, "%s()\n", __func__);
- iio_device_unregister(indio_dev);
- iio_device_free(indio_dev);
-
- return 0;
}
#ifdef CONFIG_PM_SLEEP
@@ -669,7 +654,6 @@ static struct i2c_driver isl29018_driver = {
.of_match_table = isl29018_of_match,
},
.probe = isl29018_probe,
- .remove = isl29018_remove,
.id_table = isl29018_id,
};
module_i2c_driver(isl29018_driver);
diff --git a/drivers/staging/iio/light/isl29028.c b/drivers/staging/iio/light/isl29028.c
index 8bb0d03627f..6014625920b 100644
--- a/drivers/staging/iio/light/isl29028.c
+++ b/drivers/staging/iio/light/isl29028.c
@@ -482,7 +482,7 @@ static int isl29028_probe(struct i2c_client *client,
struct iio_dev *indio_dev;
int ret;
- indio_dev = iio_device_alloc(sizeof(*chip));
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
if (!indio_dev) {
dev_err(&client->dev, "iio allocation fails\n");
return -ENOMEM;
@@ -498,13 +498,13 @@ static int isl29028_probe(struct i2c_client *client,
if (IS_ERR(chip->regmap)) {
ret = PTR_ERR(chip->regmap);
dev_err(chip->dev, "regmap initialization failed: %d\n", ret);
- goto exit_iio_free;
+ return ret;
}
ret = isl29028_chip_init(chip);
if (ret < 0) {
dev_err(chip->dev, "chip initialization failed: %d\n", ret);
- goto exit_iio_free;
+ return ret;
}
indio_dev->info = &isl29028_info;
@@ -517,13 +517,9 @@ static int isl29028_probe(struct i2c_client *client,
if (ret < 0) {
dev_err(chip->dev, "iio registration fails with error %d\n",
ret);
- goto exit_iio_free;
+ return ret;
}
return 0;
-
-exit_iio_free:
- iio_device_free(indio_dev);
- return ret;
}
static int isl29028_remove(struct i2c_client *client)
@@ -531,7 +527,6 @@ static int isl29028_remove(struct i2c_client *client)
struct iio_dev *indio_dev = i2c_get_clientdata(client);
iio_device_unregister(indio_dev);
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/light/tsl2583.c b/drivers/staging/iio/light/tsl2583.c
index b377dd3b76a..fa964987966 100644
--- a/drivers/staging/iio/light/tsl2583.c
+++ b/drivers/staging/iio/light/tsl2583.c
@@ -165,8 +165,9 @@ taos_i2c_read(struct i2c_client *client, u8 reg, u8 *val, unsigned int len)
/* select register to write */
ret = i2c_smbus_write_byte(client, (TSL258X_CMD_REG | reg));
if (ret < 0) {
- dev_err(&client->dev, "taos_i2c_read failed to write"
- " register %x\n", reg);
+ dev_err(&client->dev,
+ "taos_i2c_read failed to write register %x\n",
+ reg);
return ret;
}
/* read the data */
@@ -211,7 +212,7 @@ static int taos_get_lux(struct iio_dev *indio_dev)
if (chip->taos_chip_status != TSL258X_CHIP_WORKING) {
/* device is not enabled */
dev_err(&chip->client->dev, "taos_get_lux device is not enabled\n");
- ret = -EBUSY ;
+ ret = -EBUSY;
goto out_unlock;
}
@@ -231,8 +232,9 @@ static int taos_get_lux(struct iio_dev *indio_dev)
int reg = TSL258X_CMD_REG | (TSL258X_ALS_CHAN0LO + i);
ret = taos_i2c_read(chip->client, reg, &buf[i], 1);
if (ret < 0) {
- dev_err(&chip->client->dev, "taos_get_lux failed to read"
- " register %x\n", reg);
+ dev_err(&chip->client->dev,
+ "taos_get_lux failed to read register %x\n",
+ reg);
goto out_unlock;
}
}
@@ -433,7 +435,7 @@ static int taos_chip_on(struct iio_dev *indio_dev)
TSL258X_CMD_REG | TSL258X_CNTRL, utmp);
if (ret < 0) {
dev_err(&chip->client->dev, "taos_chip_on failed on CNTRL reg.\n");
- return -1;
+ return ret;
}
/* Use the following shadow copy for our delay before enabling ADC.
@@ -445,11 +447,11 @@ static int taos_chip_on(struct iio_dev *indio_dev)
if (ret < 0) {
dev_err(&chip->client->dev,
"taos_chip_on failed on reg %d.\n", i);
- return -1;
+ return ret;
}
}
- msleep(3);
+ usleep_range(3000, 3500);
/* NOW enable the ADC
* initialize the desired mode of operation */
utmp = TSL258X_CNTL_PWR_ON | TSL258X_CNTL_ADC_ENBL;
@@ -458,7 +460,7 @@ static int taos_chip_on(struct iio_dev *indio_dev)
utmp);
if (ret < 0) {
dev_err(&chip->client->dev, "taos_chip_on failed on 2nd CTRL reg.\n");
- return -1;
+ return ret;
}
chip->taos_chip_status = TSL258X_CHIP_WORKING;
@@ -493,9 +495,9 @@ static ssize_t taos_power_state_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- unsigned long value;
+ int value;
- if (strict_strtoul(buf, 0, &value))
+ if (kstrtoint(buf, 0, &value))
return -EINVAL;
if (value == 0)
@@ -536,9 +538,9 @@ static ssize_t taos_gain_store(struct device *dev,
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct tsl2583_chip *chip = iio_priv(indio_dev);
- unsigned long value;
+ int value;
- if (strict_strtoul(buf, 0, &value))
+ if (kstrtoint(buf, 0, &value))
return -EINVAL;
switch (value) {
@@ -582,9 +584,9 @@ static ssize_t taos_als_time_store(struct device *dev,
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct tsl2583_chip *chip = iio_priv(indio_dev);
- unsigned long value;
+ int value;
- if (strict_strtoul(buf, 0, &value))
+ if (kstrtoint(buf, 0, &value))
return -EINVAL;
if ((value < 50) || (value > 650))
@@ -619,9 +621,9 @@ static ssize_t taos_als_trim_store(struct device *dev,
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct tsl2583_chip *chip = iio_priv(indio_dev);
- unsigned long value;
+ int value;
- if (strict_strtoul(buf, 0, &value))
+ if (kstrtoint(buf, 0, &value))
return -EINVAL;
if (value)
@@ -644,9 +646,9 @@ static ssize_t taos_als_cal_target_store(struct device *dev,
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct tsl2583_chip *chip = iio_priv(indio_dev);
- unsigned long value;
+ int value;
- if (strict_strtoul(buf, 0, &value))
+ if (kstrtoint(buf, 0, &value))
return -EINVAL;
if (value)
@@ -671,9 +673,9 @@ static ssize_t taos_do_calibrate(struct device *dev,
struct device_attribute *attr, const char *buf, size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- unsigned long value;
+ int value;
- if (strict_strtoul(buf, 0, &value))
+ if (kstrtoint(buf, 0, &value))
return -EINVAL;
if (value == 1)
@@ -809,18 +811,13 @@ static int taos_probe(struct i2c_client *clientp,
if (!i2c_check_functionality(clientp->adapter,
I2C_FUNC_SMBUS_BYTE_DATA)) {
- dev_err(&clientp->dev,
- "taos_probe() - i2c smbus byte data "
- "functions unsupported\n");
+ dev_err(&clientp->dev, "taos_probe() - i2c smbus byte data func unsupported\n");
return -EOPNOTSUPP;
}
- indio_dev = iio_device_alloc(sizeof(*chip));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- dev_err(&clientp->dev, "iio allocation failed\n");
- goto fail1;
- }
+ indio_dev = devm_iio_device_alloc(&clientp->dev, sizeof(*chip));
+ if (!indio_dev)
+ return -ENOMEM;
chip = iio_priv(indio_dev);
chip->client = clientp;
i2c_set_clientdata(clientp, indio_dev);
@@ -833,31 +830,33 @@ static int taos_probe(struct i2c_client *clientp,
ret = i2c_smbus_write_byte(clientp,
(TSL258X_CMD_REG | (TSL258X_CNTRL + i)));
if (ret < 0) {
- dev_err(&clientp->dev, "i2c_smbus_write_bytes() to cmd "
- "reg failed in taos_probe(), err = %d\n", ret);
- goto fail2;
+ dev_err(&clientp->dev,
+ "i2c_smbus_write_byte to cmd reg failed in taos_probe(), err = %d\n",
+ ret);
+ return ret;
}
ret = i2c_smbus_read_byte(clientp);
if (ret < 0) {
- dev_err(&clientp->dev, "i2c_smbus_read_byte from "
- "reg failed in taos_probe(), err = %d\n", ret);
-
- goto fail2;
+ dev_err(&clientp->dev,
+ "i2c_smbus_read_byte from reg failed in taos_probe(), err = %d\n",
+ ret);
+ return ret;
}
buf[i] = ret;
}
if (!taos_tsl258x_device(buf)) {
- dev_info(&clientp->dev, "i2c device found but does not match "
- "expected id in taos_probe()\n");
- goto fail2;
+ dev_info(&clientp->dev,
+ "i2c device found but does not match expected id in taos_probe()\n");
+ return -EINVAL;
}
ret = i2c_smbus_write_byte(clientp, (TSL258X_CMD_REG | TSL258X_CNTRL));
if (ret < 0) {
- dev_err(&clientp->dev, "i2c_smbus_write_byte() to cmd reg "
- "failed in taos_probe(), err = %d\n", ret);
- goto fail2;
+ dev_err(&clientp->dev,
+ "i2c_smbus_write_byte() to cmd reg failed in taos_probe(), err = %d\n",
+ ret);
+ return ret;
}
indio_dev->info = &tsl2583_info;
@@ -867,7 +866,7 @@ static int taos_probe(struct i2c_client *clientp,
ret = iio_device_register(indio_dev);
if (ret) {
dev_err(&clientp->dev, "iio registration failed\n");
- goto fail2;
+ return ret;
}
/* Load up the V2 defaults (these are hard coded defaults for now) */
@@ -878,10 +877,6 @@ static int taos_probe(struct i2c_client *clientp,
dev_info(&clientp->dev, "Light sensor found.\n");
return 0;
-fail1:
- iio_device_free(indio_dev);
-fail2:
- return ret;
}
#ifdef CONFIG_PM_SLEEP
@@ -926,7 +921,6 @@ static SIMPLE_DEV_PM_OPS(taos_pm_ops, taos_suspend, taos_resume);
static int taos_remove(struct i2c_client *client)
{
iio_device_unregister(i2c_get_clientdata(client));
- iio_device_free(i2c_get_clientdata(client));
return 0;
}
diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x_core.c
index c99f890cc6c..ab338e3ddd0 100644
--- a/drivers/staging/iio/light/tsl2x7x_core.c
+++ b/drivers/staging/iio/light/tsl2x7x_core.c
@@ -124,11 +124,6 @@
#define TSL2X7X_mA13 0xD0
#define TSL2X7X_MAX_TIMER_CNT (0xFF)
-/*Common device IIO EventMask */
-#define TSL2X7X_EVENT_MASK \
- (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | \
- IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)),
-
#define TSL2X7X_MIN_ITIME 3
/* TAOS txx2x7x Device family members */
@@ -357,7 +352,7 @@ static int tsl2x7x_get_lux(struct iio_dev *indio_dev)
/* device is not enabled */
dev_err(&chip->client->dev, "%s: device is not enabled\n",
__func__);
- ret = -EBUSY ;
+ ret = -EBUSY;
goto out_unlock;
}
@@ -550,7 +545,7 @@ prox_poll_err:
static void tsl2x7x_defaults(struct tsl2X7X_chip *chip)
{
/* If Operational settings defined elsewhere.. */
- if (chip->pdata && chip->pdata->platform_default_settings != 0)
+ if (chip->pdata && chip->pdata->platform_default_settings)
memcpy(&(chip->tsl2x7x_settings),
chip->pdata->platform_default_settings,
sizeof(tsl2x7x_default_settings));
@@ -672,9 +667,13 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev)
chip->tsl2x7x_config[TSL2X7X_PRX_COUNT] =
chip->tsl2x7x_settings.prox_pulse_count;
chip->tsl2x7x_config[TSL2X7X_PRX_MINTHRESHLO] =
- chip->tsl2x7x_settings.prox_thres_low;
+ (chip->tsl2x7x_settings.prox_thres_low) & 0xFF;
+ chip->tsl2x7x_config[TSL2X7X_PRX_MINTHRESHHI] =
+ (chip->tsl2x7x_settings.prox_thres_low >> 8) & 0xFF;
chip->tsl2x7x_config[TSL2X7X_PRX_MAXTHRESHLO] =
- chip->tsl2x7x_settings.prox_thres_high;
+ (chip->tsl2x7x_settings.prox_thres_high) & 0xFF;
+ chip->tsl2x7x_config[TSL2X7X_PRX_MAXTHRESHHI] =
+ (chip->tsl2x7x_settings.prox_thres_high >> 8) & 0xFF;
/* and make sure we're not already on */
if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_WORKING) {
@@ -951,7 +950,6 @@ static ssize_t tsl2x7x_gain_available_show(struct device *dev,
case tsl2771:
case tmd2771:
return snprintf(buf, PAGE_SIZE, "%s\n", "1 8 16 128");
- break;
}
return snprintf(buf, PAGE_SIZE, "%s\n", "1 8 16 120");
@@ -1223,12 +1221,14 @@ static ssize_t tsl2x7x_do_prox_calibrate(struct device *dev,
}
static int tsl2x7x_read_interrupt_config(struct iio_dev *indio_dev,
- u64 event_code)
+ const struct iio_chan_spec *chan,
+ enum iio_event_type type,
+ enum iio_event_direction dir)
{
struct tsl2X7X_chip *chip = iio_priv(indio_dev);
int ret;
- if (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code) == IIO_INTENSITY)
+ if (chan->type == IIO_INTENSITY)
ret = !!(chip->tsl2x7x_settings.interrupts_en & 0x10);
else
ret = !!(chip->tsl2x7x_settings.interrupts_en & 0x20);
@@ -1237,12 +1237,14 @@ static int tsl2x7x_read_interrupt_config(struct iio_dev *indio_dev,
}
static int tsl2x7x_write_interrupt_config(struct iio_dev *indio_dev,
- u64 event_code,
+ const struct iio_chan_spec *chan,
+ enum iio_event_type type,
+ enum iio_event_direction dir,
int val)
{
struct tsl2X7X_chip *chip = iio_priv(indio_dev);
- if (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code) == IIO_INTENSITY) {
+ if (chan->type == IIO_INTENSITY) {
if (val)
chip->tsl2x7x_settings.interrupts_en |= 0x10;
else
@@ -1260,13 +1262,16 @@ static int tsl2x7x_write_interrupt_config(struct iio_dev *indio_dev,
}
static int tsl2x7x_write_thresh(struct iio_dev *indio_dev,
- u64 event_code,
- int val)
+ 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 tsl2X7X_chip *chip = iio_priv(indio_dev);
- if (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code) == IIO_INTENSITY) {
- switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
+ if (chan->type == IIO_INTENSITY) {
+ switch (dir) {
case IIO_EV_DIR_RISING:
chip->tsl2x7x_settings.als_thresh_high = val;
break;
@@ -1277,7 +1282,7 @@ static int tsl2x7x_write_thresh(struct iio_dev *indio_dev,
return -EINVAL;
}
} else {
- switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
+ switch (dir) {
case IIO_EV_DIR_RISING:
chip->tsl2x7x_settings.prox_thres_high = val;
break;
@@ -1295,13 +1300,16 @@ static int tsl2x7x_write_thresh(struct iio_dev *indio_dev,
}
static int tsl2x7x_read_thresh(struct iio_dev *indio_dev,
- u64 event_code,
- int *val)
+ 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 tsl2X7X_chip *chip = iio_priv(indio_dev);
- if (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code) == IIO_INTENSITY) {
- switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
+ if (chan->type == IIO_INTENSITY) {
+ switch (dir) {
case IIO_EV_DIR_RISING:
*val = chip->tsl2x7x_settings.als_thresh_high;
break;
@@ -1312,7 +1320,7 @@ static int tsl2x7x_read_thresh(struct iio_dev *indio_dev,
return -EINVAL;
}
} else {
- switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
+ switch (dir) {
case IIO_EV_DIR_RISING:
*val = chip->tsl2x7x_settings.prox_thres_high;
break;
@@ -1324,7 +1332,7 @@ static int tsl2x7x_read_thresh(struct iio_dev *indio_dev,
}
}
- return 0;
+ return IIO_VAL_INT;
}
static int tsl2x7x_read_raw(struct iio_dev *indio_dev,
@@ -1346,7 +1354,6 @@ static int tsl2x7x_read_raw(struct iio_dev *indio_dev,
break;
default:
return -EINVAL;
- break;
}
break;
case IIO_CHAN_INFO_RAW:
@@ -1366,7 +1373,6 @@ static int tsl2x7x_read_raw(struct iio_dev *indio_dev,
break;
default:
return -EINVAL;
- break;
}
break;
case IIO_CHAN_INFO_CALIBSCALE:
@@ -1419,7 +1425,6 @@ static int tsl2x7x_write_raw(struct iio_dev *indio_dev,
case tsl2772:
case tmd2772:
return -EINVAL;
- break;
}
chip->tsl2x7x_settings.als_gain = 3;
break;
@@ -1431,7 +1436,6 @@ static int tsl2x7x_write_raw(struct iio_dev *indio_dev,
case tsl2771:
case tmd2771:
return -EINVAL;
- break;
}
chip->tsl2x7x_settings.als_gain = 3;
break;
@@ -1507,19 +1511,16 @@ static int tsl2x7x_device_id(unsigned char *id, int target)
case tsl2571:
case tsl2671:
case tsl2771:
- return ((*id & 0xf0) == TRITON_ID);
- break;
+ return (*id & 0xf0) == TRITON_ID;
case tmd2671:
case tmd2771:
- return ((*id & 0xf0) == HALIBUT_ID);
- break;
+ return (*id & 0xf0) == HALIBUT_ID;
case tsl2572:
case tsl2672:
case tmd2672:
case tsl2772:
case tmd2772:
- return ((*id & 0xf0) == SWORDFISH_ID);
- break;
+ return (*id & 0xf0) == SWORDFISH_ID;
}
return -EINVAL;
@@ -1726,6 +1727,20 @@ static const struct iio_info tsl2X7X_device_info[] = {
},
};
+static const struct iio_event_spec tsl2x7x_events[] = {
+ {
+ .type = IIO_EV_TYPE_THRESH,
+ .dir = IIO_EV_DIR_RISING,
+ .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+ BIT(IIO_EV_INFO_ENABLE),
+ }, {
+ .type = IIO_EV_TYPE_THRESH,
+ .dir = IIO_EV_DIR_FALLING,
+ .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+ BIT(IIO_EV_INFO_ENABLE),
+ },
+};
+
static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
[ALS] = {
.channel = {
@@ -1741,7 +1756,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_CALIBSCALE) |
BIT(IIO_CHAN_INFO_CALIBBIAS),
- .event_mask = TSL2X7X_EVENT_MASK
+ .event_spec = tsl2x7x_events,
+ .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
}, {
.type = IIO_INTENSITY,
.indexed = 1,
@@ -1758,7 +1774,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
.indexed = 1,
.channel = 0,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
- .event_mask = TSL2X7X_EVENT_MASK
+ .event_spec = tsl2x7x_events,
+ .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
},
},
.chan_table_elements = 1,
@@ -1778,7 +1795,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_CALIBSCALE) |
BIT(IIO_CHAN_INFO_CALIBBIAS),
- .event_mask = TSL2X7X_EVENT_MASK
+ .event_spec = tsl2x7x_events,
+ .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
}, {
.type = IIO_INTENSITY,
.indexed = 1,
@@ -1789,7 +1807,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
.indexed = 1,
.channel = 0,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
- .event_mask = TSL2X7X_EVENT_MASK
+ .event_spec = tsl2x7x_events,
+ .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
},
},
.chan_table_elements = 4,
@@ -1803,7 +1822,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
.channel = 0,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_CALIBSCALE),
- .event_mask = TSL2X7X_EVENT_MASK
+ .event_spec = tsl2x7x_events,
+ .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
},
},
.chan_table_elements = 1,
@@ -1823,7 +1843,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_CALIBSCALE) |
BIT(IIO_CHAN_INFO_CALIBBIAS),
- .event_mask = TSL2X7X_EVENT_MASK
+ .event_spec = tsl2x7x_events,
+ .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
}, {
.type = IIO_INTENSITY,
.indexed = 1,
@@ -1835,7 +1856,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
.channel = 0,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_CALIBSCALE),
- .event_mask = TSL2X7X_EVENT_MASK
+ .event_spec = tsl2x7x_events,
+ .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
},
},
.chan_table_elements = 4,
@@ -1851,7 +1873,7 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
struct iio_dev *indio_dev;
struct tsl2X7X_chip *chip;
- indio_dev = iio_device_alloc(sizeof(*chip));
+ indio_dev = devm_iio_device_alloc(&clientp->dev, sizeof(*chip));
if (!indio_dev)
return -ENOMEM;
@@ -1862,22 +1884,21 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
ret = tsl2x7x_i2c_read(chip->client,
TSL2X7X_CHIPID, &device_id);
if (ret < 0)
- goto fail1;
+ return ret;
if ((!tsl2x7x_device_id(&device_id, id->driver_data)) ||
(tsl2x7x_device_id(&device_id, id->driver_data) == -EINVAL)) {
dev_info(&chip->client->dev,
"%s: i2c device found does not match expected id\n",
__func__);
- ret = -EINVAL;
- goto fail1;
+ return -EINVAL;
}
ret = i2c_smbus_write_byte(clientp, (TSL2X7X_CMD_REG | TSL2X7X_CNTRL));
if (ret < 0) {
dev_err(&clientp->dev, "%s: write to cmd reg failed. err = %d\n",
__func__, ret);
- goto fail1;
+ return ret;
}
/* ALS and PROX functions can be invoked via user space poll
@@ -1899,16 +1920,17 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
indio_dev->num_channels = chip->chip_info->chan_table_elements;
if (clientp->irq) {
- ret = request_threaded_irq(clientp->irq,
- NULL,
- &tsl2x7x_event_handler,
- IRQF_TRIGGER_RISING | IRQF_ONESHOT,
- "TSL2X7X_event",
- indio_dev);
+ ret = devm_request_threaded_irq(&clientp->dev, clientp->irq,
+ NULL,
+ &tsl2x7x_event_handler,
+ IRQF_TRIGGER_RISING |
+ IRQF_ONESHOT,
+ "TSL2X7X_event",
+ indio_dev);
if (ret) {
dev_err(&clientp->dev,
"%s: irq request failed", __func__);
- goto fail1;
+ return ret;
}
}
@@ -1921,20 +1943,12 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
if (ret) {
dev_err(&clientp->dev,
"%s: iio registration failed\n", __func__);
- goto fail2;
+ return ret;
}
dev_info(&clientp->dev, "%s Light sensor found.\n", id->name);
return 0;
-
-fail2:
- if (clientp->irq)
- free_irq(clientp->irq, indio_dev);
-fail1:
- iio_device_free(indio_dev);
-
- return ret;
}
static int tsl2x7x_suspend(struct device *dev)
@@ -1980,10 +1994,6 @@ static int tsl2x7x_remove(struct i2c_client *client)
tsl2x7x_chip_off(indio_dev);
iio_device_unregister(indio_dev);
- if (client->irq)
- free_irq(client->irq, indio_dev);
-
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/magnetometer/Kconfig b/drivers/staging/iio/magnetometer/Kconfig
index a3ea69e9d80..34634da1f9f 100644
--- a/drivers/staging/iio/magnetometer/Kconfig
+++ b/drivers/staging/iio/magnetometer/Kconfig
@@ -6,6 +6,8 @@ menu "Magnetometer sensors"
config SENSORS_HMC5843
tristate "Honeywell HMC5843/5883/5883L 3-Axis Magnetometer"
depends on I2C
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
help
Say Y here to add support for the Honeywell HMC5843, HMC5883 and
HMC5883L 3-Axis Magnetometer (digital compass).
diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c
index 86c6bf9d5dd..d4f4dd90c69 100644
--- a/drivers/staging/iio/magnetometer/hmc5843.c
+++ b/drivers/staging/iio/magnetometer/hmc5843.c
@@ -20,31 +20,20 @@
*/
#include <linux/module.h>
-#include <linux/init.h>
#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/types.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/delay.h>
#define HMC5843_CONFIG_REG_A 0x00
#define HMC5843_CONFIG_REG_B 0x01
#define HMC5843_MODE_REG 0x02
-#define HMC5843_DATA_OUT_X_MSB_REG 0x03
-#define HMC5843_DATA_OUT_X_LSB_REG 0x04
-#define HMC5843_DATA_OUT_Y_MSB_REG 0x05
-#define HMC5843_DATA_OUT_Y_LSB_REG 0x06
-#define HMC5843_DATA_OUT_Z_MSB_REG 0x07
-#define HMC5843_DATA_OUT_Z_LSB_REG 0x08
-/* Beware: Y and Z are exchanged on HMC5883 */
-#define HMC5883_DATA_OUT_Z_MSB_REG 0x05
-#define HMC5883_DATA_OUT_Z_LSB_REG 0x06
-#define HMC5883_DATA_OUT_Y_MSB_REG 0x07
-#define HMC5883_DATA_OUT_Y_LSB_REG 0x08
+#define HMC5843_DATA_OUT_MSB_REGS 0x03
#define HMC5843_STATUS_REG 0x09
-#define HMC5843_ID_REG_A 0x0A
-#define HMC5843_ID_REG_B 0x0B
-#define HMC5843_ID_REG_C 0x0C
+#define HMC5843_ID_REG 0x0a
enum hmc5843_ids {
HMC5843_ID,
@@ -53,33 +42,19 @@ enum hmc5843_ids {
};
/*
- * Beware: identification of the HMC5883 is still "H43";
- * I2C address is also unchanged
- */
-#define HMC5843_ID_REG_LENGTH 0x03
-#define HMC5843_ID_STRING "H43"
-#define HMC5843_I2C_ADDRESS 0x1E
-
-/*
* Range gain settings in (+-)Ga
* Beware: HMC5843 and HMC5883 have different recommended sensor field
* ranges; default corresponds to +-1.0 Ga and +-1.3 Ga, respectively
*/
#define HMC5843_RANGE_GAIN_OFFSET 0x05
#define HMC5843_RANGE_GAIN_DEFAULT 0x01
-#define HMC5843_RANGE_GAIN_MAX 0x07
+#define HMC5843_RANGE_GAINS 8
-/*
- * Device status
- */
+/* Device status */
#define HMC5843_DATA_READY 0x01
#define HMC5843_DATA_OUTPUT_LOCK 0x02
-/* Does not exist on HMC5883, not used */
-#define HMC5843_VOLTAGE_REGULATOR_ENABLED 0x04
-/*
- * Mode register configuration
- */
+/* Mode register configuration */
#define HMC5843_MODE_CONVERSION_CONTINUOUS 0x00
#define HMC5843_MODE_CONVERSION_SINGLE 0x01
#define HMC5843_MODE_IDLE 0x02
@@ -91,80 +66,29 @@ enum hmc5843_ids {
* HMC5883: Typical data output rate
*/
#define HMC5843_RATE_OFFSET 0x02
-#define HMC5843_RATE_BITMASK 0x1C
-#define HMC5843_RATE_NOT_USED 0x07
+#define HMC5843_RATE_DEFAULT 0x04
+#define HMC5843_RATES 7
-/*
- * Device measurement configuration
- */
+/* Device measurement configuration */
#define HMC5843_MEAS_CONF_NORMAL 0x00
#define HMC5843_MEAS_CONF_POSITIVE_BIAS 0x01
#define HMC5843_MEAS_CONF_NEGATIVE_BIAS 0x02
-#define HMC5843_MEAS_CONF_NOT_USED 0x03
#define HMC5843_MEAS_CONF_MASK 0x03
-/*
- * Scaling factors: 10000000/Gain
- */
-static const int hmc5843_regval_to_nanoscale[] = {
+/* Scaling factors: 10000000/Gain */
+static const int hmc5843_regval_to_nanoscale[HMC5843_RANGE_GAINS] = {
6173, 7692, 10309, 12821, 18868, 21739, 25641, 35714
};
-static const int hmc5883_regval_to_nanoscale[] = {
+static const int hmc5883_regval_to_nanoscale[HMC5843_RANGE_GAINS] = {
7812, 9766, 13021, 16287, 24096, 27701, 32573, 45662
};
-static const int hmc5883l_regval_to_nanoscale[] = {
+static const int hmc5883l_regval_to_nanoscale[HMC5843_RANGE_GAINS] = {
7299, 9174, 12195, 15152, 22727, 25641, 30303, 43478
};
/*
- * From the HMC5843 datasheet:
- * Value | Sensor input field range (Ga) | Gain (counts/milli-Gauss)
- * 0 | (+-)0.7 | 1620
- * 1 | (+-)1.0 | 1300
- * 2 | (+-)1.5 | 970
- * 3 | (+-)2.0 | 780
- * 4 | (+-)3.2 | 530
- * 5 | (+-)3.8 | 460
- * 6 | (+-)4.5 | 390
- * 7 | (+-)6.5 | 280
- *
- * From the HMC5883 datasheet:
- * Value | Recommended sensor field range (Ga) | Gain (counts/Gauss)
- * 0 | (+-)0.9 | 1280
- * 1 | (+-)1.2 | 1024
- * 2 | (+-)1.9 | 768
- * 3 | (+-)2.5 | 614
- * 4 | (+-)4.0 | 415
- * 5 | (+-)4.6 | 361
- * 6 | (+-)5.5 | 307
- * 7 | (+-)7.9 | 219
- *
- * From the HMC5883L datasheet:
- * Value | Recommended sensor field range (Ga) | Gain (LSB/Gauss)
- * 0 | (+-)0.88 | 1370
- * 1 | (+-)1.3 | 1090
- * 2 | (+-)1.9 | 820
- * 3 | (+-)2.5 | 660
- * 4 | (+-)4.0 | 440
- * 5 | (+-)4.7 | 390
- * 6 | (+-)5.6 | 330
- * 7 | (+-)8.1 | 230
- */
-static const int hmc5843_regval_to_input_field_mga[] = {
- 700, 1000, 1500, 2000, 3200, 3800, 4500, 6500
-};
-
-static const int hmc5883_regval_to_input_field_mga[] = {
- 900, 1200, 1900, 2500, 4000, 4600, 5500, 7900
-};
-
-static const int hmc5883l_regval_to_input_field_mga[] = {
- 880, 1300, 1900, 2500, 4000, 4700, 5600, 8100
-};
-
-/*
* From the datasheet:
* Value | HMC5843 | HMC5883/HMC5883L
* | Data output rate (Hz) | Data output rate (Hz)
@@ -177,135 +101,94 @@ static const int hmc5883l_regval_to_input_field_mga[] = {
* 6 | 50 | 75
* 7 | Not used | Not used
*/
-static const char * const hmc5843_regval_to_sample_freq[] = {
- "0.5", "1", "2", "5", "10", "20", "50",
+static const int hmc5843_regval_to_samp_freq[7][2] = {
+ {0, 500000}, {1, 0}, {2, 0}, {5, 0}, {10, 0}, {20, 0}, {50, 0}
};
-static const char * const hmc5883_regval_to_sample_freq[] = {
- "0.75", "1.5", "3", "7.5", "15", "30", "75",
+static const int hmc5883_regval_to_samp_freq[7][2] = {
+ {0, 750000}, {1, 500000}, {3, 0}, {7, 500000}, {15, 0}, {30, 0},
+ {75, 0}
};
-/* Addresses to scan: 0x1E */
-static const unsigned short normal_i2c[] = { HMC5843_I2C_ADDRESS,
- I2C_CLIENT_END };
-
/* Describe chip variants */
struct hmc5843_chip_info {
const struct iio_chan_spec *channels;
- int num_channels;
- const char * const *regval_to_sample_freq;
- const int *regval_to_input_field_mga;
+ const int (*regval_to_samp_freq)[2];
const int *regval_to_nanoscale;
};
/* Each client has this additional data */
struct hmc5843_data {
+ struct i2c_client *client;
struct mutex lock;
u8 rate;
u8 meas_conf;
u8 operating_mode;
u8 range;
const struct hmc5843_chip_info *variant;
+ __be16 buffer[8]; /* 3x 16-bit channels + padding + 64-bit timestamp */
};
/* The lower two bits contain the current conversion mode */
-static s32 hmc5843_configure(struct i2c_client *client,
- u8 operating_mode)
+static s32 hmc5843_set_mode(struct hmc5843_data *data, u8 operating_mode)
{
- return i2c_smbus_write_byte_data(client,
- HMC5843_MODE_REG,
- operating_mode & HMC5843_MODE_MASK);
-}
-
-/* Return the measurement value from the specified channel */
-static int hmc5843_read_measurement(struct iio_dev *indio_dev,
- int address,
- int *val)
-{
- struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
- struct hmc5843_data *data = iio_priv(indio_dev);
- s32 result;
+ int ret;
mutex_lock(&data->lock);
- result = i2c_smbus_read_byte_data(client, HMC5843_STATUS_REG);
- while (!(result & HMC5843_DATA_READY))
- result = i2c_smbus_read_byte_data(client, HMC5843_STATUS_REG);
-
- result = i2c_smbus_read_word_data(client, address);
+ ret = i2c_smbus_write_byte_data(data->client, HMC5843_MODE_REG,
+ operating_mode & HMC5843_MODE_MASK);
+ if (ret >= 0)
+ data->operating_mode = operating_mode;
mutex_unlock(&data->lock);
- if (result < 0)
- return -EINVAL;
- *val = (s16)swab16((u16)result);
- return IIO_VAL_INT;
+ return ret;
}
-/*
- * From the datasheet:
- * 0 - Continuous-Conversion Mode: In continuous-conversion mode, the
- * device continuously performs conversions and places the result in
- * the data register.
- *
- * 1 - Single-Conversion Mode : Device performs a single measurement,
- * sets RDY high and returns to sleep mode.
- *
- * 2 - Idle Mode : Device is placed in idle mode.
- *
- * 3 - Sleep Mode : Device is placed in sleep mode.
- *
- */
-static ssize_t hmc5843_show_operating_mode(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+static int hmc5843_wait_measurement(struct hmc5843_data *data)
{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct hmc5843_data *data = iio_priv(indio_dev);
- return sprintf(buf, "%d\n", data->operating_mode);
+ s32 result;
+ int tries = 150;
+
+ while (tries-- > 0) {
+ result = i2c_smbus_read_byte_data(data->client,
+ HMC5843_STATUS_REG);
+ if (result < 0)
+ return result;
+ if (result & HMC5843_DATA_READY)
+ break;
+ msleep(20);
+ }
+
+ if (tries < 0) {
+ dev_err(&data->client->dev, "data not ready\n");
+ return -EIO;
+ }
+
+ return 0;
}
-static ssize_t hmc5843_set_operating_mode(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t count)
+/* Return the measurement value from the specified channel */
+static int hmc5843_read_measurement(struct hmc5843_data *data,
+ int idx, int *val)
{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
- struct hmc5843_data *data = iio_priv(indio_dev);
- struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
- unsigned long operating_mode = 0;
- s32 status;
- int error;
+ s32 result;
+ __be16 values[3];
mutex_lock(&data->lock);
- error = kstrtoul(buf, 10, &operating_mode);
- if (error) {
- count = error;
- goto exit;
- }
- dev_dbg(dev, "set conversion mode to %lu\n", operating_mode);
- if (operating_mode > HMC5843_MODE_SLEEP) {
- count = -EINVAL;
- goto exit;
- }
-
- status = i2c_smbus_write_byte_data(client, this_attr->address,
- operating_mode);
- if (status) {
- count = -EINVAL;
- goto exit;
+ result = hmc5843_wait_measurement(data);
+ if (result < 0) {
+ mutex_unlock(&data->lock);
+ return result;
}
- data->operating_mode = operating_mode;
-
-exit:
+ result = i2c_smbus_read_i2c_block_data(data->client,
+ HMC5843_DATA_OUT_MSB_REGS, sizeof(values), (u8 *) values);
mutex_unlock(&data->lock);
- return count;
-}
+ if (result < 0)
+ return -EINVAL;
-static IIO_DEVICE_ATTR(operating_mode,
- S_IWUSR | S_IRUGO,
- hmc5843_show_operating_mode,
- hmc5843_set_operating_mode,
- HMC5843_MODE_REG);
+ *val = sign_extend32(be16_to_cpu(values[idx]), 15);
+ return IIO_VAL_INT;
+}
/*
* API for setting the measurement configuration to
@@ -325,23 +208,26 @@ static IIO_DEVICE_ATTR(operating_mode,
* and BN.
*
*/
-static s32 hmc5843_set_meas_conf(struct i2c_client *client,
- u8 meas_conf)
+static s32 hmc5843_set_meas_conf(struct hmc5843_data *data, u8 meas_conf)
{
- struct iio_dev *indio_dev = i2c_get_clientdata(client);
- struct hmc5843_data *data = iio_priv(indio_dev);
- u8 reg_val;
- reg_val = (meas_conf & HMC5843_MEAS_CONF_MASK) |
- (data->rate << HMC5843_RATE_OFFSET);
- return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val);
+ int ret;
+
+ mutex_lock(&data->lock);
+ ret = i2c_smbus_write_byte_data(data->client, HMC5843_CONFIG_REG_A,
+ (meas_conf & HMC5843_MEAS_CONF_MASK) |
+ (data->rate << HMC5843_RATE_OFFSET));
+ if (ret >= 0)
+ data->meas_conf = meas_conf;
+ mutex_unlock(&data->lock);
+
+ return ret;
}
static ssize_t hmc5843_show_measurement_configuration(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct hmc5843_data *data = iio_priv(indio_dev);
+ struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
return sprintf(buf, "%d\n", data->meas_conf);
}
@@ -350,29 +236,19 @@ static ssize_t hmc5843_set_measurement_configuration(struct device *dev,
const char *buf,
size_t count)
{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
- struct hmc5843_data *data = iio_priv(indio_dev);
+ struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
unsigned long meas_conf = 0;
- int error;
+ int ret;
- error = kstrtoul(buf, 10, &meas_conf);
- if (error)
- return error;
- if (meas_conf >= HMC5843_MEAS_CONF_NOT_USED)
+ ret = kstrtoul(buf, 10, &meas_conf);
+ if (ret)
+ return ret;
+ if (meas_conf >= HMC5843_MEAS_CONF_MASK)
return -EINVAL;
- mutex_lock(&data->lock);
- dev_dbg(dev, "set measurement configuration to %lu\n", meas_conf);
- if (hmc5843_set_meas_conf(client, meas_conf)) {
- count = -EINVAL;
- goto exit;
- }
- data->meas_conf = meas_conf;
+ ret = hmc5843_set_meas_conf(data, meas_conf);
-exit:
- mutex_unlock(&data->lock);
- return count;
+ return (ret < 0) ? ret : count;
}
static IIO_DEVICE_ATTR(meas_conf,
@@ -381,211 +257,226 @@ static IIO_DEVICE_ATTR(meas_conf,
hmc5843_set_measurement_configuration,
0);
-static ssize_t hmc5843_show_sampling_frequencies_available(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+static ssize_t hmc5843_show_samp_freq_avail(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct hmc5843_data *data = iio_priv(indio_dev);
- ssize_t total_n = 0;
+ struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
+ size_t len = 0;
int i;
- for (i = 0; i < HMC5843_RATE_NOT_USED; i++) {
- ssize_t n = sprintf(buf, "%s ", data->variant->regval_to_sample_freq[i]);
- buf += n;
- total_n += n;
- }
+ for (i = 0; i < HMC5843_RATES; i++)
+ len += scnprintf(buf + len, PAGE_SIZE - len,
+ "%d.%d ", data->variant->regval_to_samp_freq[i][0],
+ data->variant->regval_to_samp_freq[i][1]);
+
/* replace trailing space by newline */
- buf[-1] = '\n';
+ buf[len - 1] = '\n';
- return total_n;
+ return len;
}
-static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(hmc5843_show_sampling_frequencies_available);
+static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(hmc5843_show_samp_freq_avail);
-static s32 hmc5843_set_rate(struct i2c_client *client,
- u8 rate)
+static int hmc5843_set_samp_freq(struct hmc5843_data *data, u8 rate)
{
- struct iio_dev *indio_dev = i2c_get_clientdata(client);
- struct hmc5843_data *data = iio_priv(indio_dev);
- u8 reg_val;
+ int ret;
- if (rate >= HMC5843_RATE_NOT_USED) {
- dev_err(&client->dev,
- "data output rate is not supported\n");
- return -EINVAL;
- }
+ mutex_lock(&data->lock);
+ ret = i2c_smbus_write_byte_data(data->client, HMC5843_CONFIG_REG_A,
+ data->meas_conf | (rate << HMC5843_RATE_OFFSET));
+ if (ret >= 0)
+ data->rate = rate;
+ mutex_unlock(&data->lock);
- reg_val = data->meas_conf | (rate << HMC5843_RATE_OFFSET);
- return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val);
+ return ret;
}
-static int hmc5843_check_sampling_frequency(struct hmc5843_data *data,
- const char *buf)
+static int hmc5843_get_samp_freq_index(struct hmc5843_data *data,
+ int val, int val2)
{
- const char * const *samp_freq = data->variant->regval_to_sample_freq;
int i;
- for (i = 0; i < HMC5843_RATE_NOT_USED; i++) {
- if (sysfs_streq(buf, samp_freq[i]))
+ for (i = 0; i < HMC5843_RATES; i++)
+ if (val == data->variant->regval_to_samp_freq[i][0] &&
+ val2 == data->variant->regval_to_samp_freq[i][1])
return i;
- }
return -EINVAL;
}
-static ssize_t hmc5843_set_sampling_frequency(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
+static int hmc5843_set_range_gain(struct hmc5843_data *data, u8 range)
{
-
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
- struct hmc5843_data *data = iio_priv(indio_dev);
- int rate;
-
- rate = hmc5843_check_sampling_frequency(data, buf);
- if (rate < 0) {
- dev_err(&client->dev,
- "sampling frequency is not supported\n");
- return rate;
- }
+ int ret;
mutex_lock(&data->lock);
- dev_dbg(dev, "set rate to %d\n", rate);
- if (hmc5843_set_rate(client, rate)) {
- count = -EINVAL;
- goto exit;
- }
- data->rate = rate;
-
-exit:
+ ret = i2c_smbus_write_byte_data(data->client, HMC5843_CONFIG_REG_B,
+ range << HMC5843_RANGE_GAIN_OFFSET);
+ if (ret >= 0)
+ data->range = range;
mutex_unlock(&data->lock);
- return count;
+
+ return ret;
}
-static ssize_t hmc5843_show_sampling_frequency(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t hmc5843_show_scale_avail(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
- struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
- struct hmc5843_data *data = iio_priv(indio_dev);
- s32 rate;
+ struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
- rate = i2c_smbus_read_byte_data(client, this_attr->address);
- if (rate < 0)
- return rate;
- rate = (rate & HMC5843_RATE_BITMASK) >> HMC5843_RATE_OFFSET;
- return sprintf(buf, "%s\n", data->variant->regval_to_sample_freq[rate]);
-}
+ size_t len = 0;
+ int i;
-static IIO_DEVICE_ATTR(sampling_frequency,
- S_IWUSR | S_IRUGO,
- hmc5843_show_sampling_frequency,
- hmc5843_set_sampling_frequency,
- HMC5843_CONFIG_REG_A);
+ for (i = 0; i < HMC5843_RANGE_GAINS; i++)
+ len += scnprintf(buf + len, PAGE_SIZE - len,
+ "0.%09d ", data->variant->regval_to_nanoscale[i]);
-static ssize_t hmc5843_show_range_gain(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- u8 range;
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct hmc5843_data *data = iio_priv(indio_dev);
+ /* replace trailing space by newline */
+ buf[len - 1] = '\n';
- range = data->range;
- return sprintf(buf, "%d\n", data->variant->regval_to_input_field_mga[range]);
+ return len;
}
-static ssize_t hmc5843_set_range_gain(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t count)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
- struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
- struct hmc5843_data *data = iio_priv(indio_dev);
- unsigned long range = 0;
- int error;
+static IIO_DEVICE_ATTR(scale_available, S_IRUGO,
+ hmc5843_show_scale_avail, NULL, 0);
- mutex_lock(&data->lock);
- error = kstrtoul(buf, 10, &range);
- if (error) {
- count = error;
- goto exit;
- }
- dev_dbg(dev, "set range to %lu\n", range);
+static int hmc5843_get_scale_index(struct hmc5843_data *data, int val, int val2)
+{
+ int i;
- if (range > HMC5843_RANGE_GAIN_MAX) {
- count = -EINVAL;
- goto exit;
- }
+ if (val != 0)
+ return -EINVAL;
- data->range = range;
- range = range << HMC5843_RANGE_GAIN_OFFSET;
- if (i2c_smbus_write_byte_data(client, this_attr->address, range))
- count = -EINVAL;
+ for (i = 0; i < HMC5843_RANGE_GAINS; i++)
+ if (val2 == data->variant->regval_to_nanoscale[i])
+ return i;
-exit:
- mutex_unlock(&data->lock);
- return count;
+ return -EINVAL;
}
-static IIO_DEVICE_ATTR(in_magn_range,
- S_IWUSR | S_IRUGO,
- hmc5843_show_range_gain,
- hmc5843_set_range_gain,
- HMC5843_CONFIG_REG_B);
-
static int hmc5843_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
- int *val, int *val2,
- long mask)
+ int *val, int *val2, long mask)
{
struct hmc5843_data *data = iio_priv(indio_dev);
switch (mask) {
case IIO_CHAN_INFO_RAW:
- return hmc5843_read_measurement(indio_dev,
- chan->address,
- val);
+ return hmc5843_read_measurement(data, chan->scan_index, val);
case IIO_CHAN_INFO_SCALE:
*val = 0;
*val2 = data->variant->regval_to_nanoscale[data->range];
return IIO_VAL_INT_PLUS_NANO;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ *val = data->variant->regval_to_samp_freq[data->rate][0];
+ *val2 = data->variant->regval_to_samp_freq[data->rate][1];
+ return IIO_VAL_INT_PLUS_MICRO;
}
return -EINVAL;
}
-#define HMC5843_CHANNEL(axis, add) \
+static int hmc5843_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val, int val2, long mask)
+{
+ struct hmc5843_data *data = iio_priv(indio_dev);
+ int rate, range;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ rate = hmc5843_get_samp_freq_index(data, val, val2);
+ if (rate < 0)
+ return -EINVAL;
+
+ return hmc5843_set_samp_freq(data, rate);
+ case IIO_CHAN_INFO_SCALE:
+ range = hmc5843_get_scale_index(data, val, val2);
+ if (range < 0)
+ return -EINVAL;
+
+ return hmc5843_set_range_gain(data, range);
+ default:
+ return -EINVAL;
+ }
+}
+
+static int hmc5843_write_raw_get_fmt(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, long mask)
+{
+ switch (mask) {
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_CHAN_INFO_SCALE:
+ return IIO_VAL_INT_PLUS_NANO;
+ default:
+ return -EINVAL;
+ }
+}
+
+static irqreturn_t hmc5843_trigger_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct hmc5843_data *data = iio_priv(indio_dev);
+ int ret;
+
+ mutex_lock(&data->lock);
+ ret = hmc5843_wait_measurement(data);
+ if (ret < 0) {
+ mutex_unlock(&data->lock);
+ goto done;
+ }
+
+ ret = i2c_smbus_read_i2c_block_data(data->client,
+ HMC5843_DATA_OUT_MSB_REGS, 3 * sizeof(__be16),
+ (u8 *) data->buffer);
+ mutex_unlock(&data->lock);
+ if (ret < 0)
+ goto done;
+
+ iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
+ iio_get_time_ns());
+
+done:
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+}
+
+#define HMC5843_CHANNEL(axis, idx) \
{ \
.type = IIO_MAGN, \
.modified = 1, \
.channel2 = IIO_MOD_##axis, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
- .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
- .address = add \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
+ BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+ .scan_index = idx, \
+ .scan_type = { \
+ .sign = 's', \
+ .realbits = 16, \
+ .storagebits = 16, \
+ .endianness = IIO_BE, \
+ }, \
}
static const struct iio_chan_spec hmc5843_channels[] = {
- HMC5843_CHANNEL(X, HMC5843_DATA_OUT_X_MSB_REG),
- HMC5843_CHANNEL(Y, HMC5843_DATA_OUT_Y_MSB_REG),
- HMC5843_CHANNEL(Z, HMC5843_DATA_OUT_Z_MSB_REG),
+ HMC5843_CHANNEL(X, 0),
+ HMC5843_CHANNEL(Y, 1),
+ HMC5843_CHANNEL(Z, 2),
+ IIO_CHAN_SOFT_TIMESTAMP(3),
};
+/* Beware: Y and Z are exchanged on HMC5883 */
static const struct iio_chan_spec hmc5883_channels[] = {
- HMC5843_CHANNEL(X, HMC5843_DATA_OUT_X_MSB_REG),
- HMC5843_CHANNEL(Y, HMC5883_DATA_OUT_Y_MSB_REG),
- HMC5843_CHANNEL(Z, HMC5883_DATA_OUT_Z_MSB_REG),
+ HMC5843_CHANNEL(X, 0),
+ HMC5843_CHANNEL(Z, 1),
+ HMC5843_CHANNEL(Y, 2),
+ IIO_CHAN_SOFT_TIMESTAMP(3),
};
static struct attribute *hmc5843_attributes[] = {
&iio_dev_attr_meas_conf.dev_attr.attr,
- &iio_dev_attr_operating_mode.dev_attr.attr,
- &iio_dev_attr_sampling_frequency.dev_attr.attr,
- &iio_dev_attr_in_magn_range.dev_attr.attr,
+ &iio_dev_attr_scale_available.dev_attr.attr,
&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
NULL
};
@@ -597,111 +488,101 @@ static const struct attribute_group hmc5843_group = {
static const struct hmc5843_chip_info hmc5843_chip_info_tbl[] = {
[HMC5843_ID] = {
.channels = hmc5843_channels,
- .num_channels = ARRAY_SIZE(hmc5843_channels),
- .regval_to_sample_freq = hmc5843_regval_to_sample_freq,
- .regval_to_input_field_mga =
- hmc5843_regval_to_input_field_mga,
+ .regval_to_samp_freq = hmc5843_regval_to_samp_freq,
.regval_to_nanoscale = hmc5843_regval_to_nanoscale,
},
[HMC5883_ID] = {
.channels = hmc5883_channels,
- .num_channels = ARRAY_SIZE(hmc5883_channels),
- .regval_to_sample_freq = hmc5883_regval_to_sample_freq,
- .regval_to_input_field_mga =
- hmc5883_regval_to_input_field_mga,
+ .regval_to_samp_freq = hmc5883_regval_to_samp_freq,
.regval_to_nanoscale = hmc5883_regval_to_nanoscale,
},
[HMC5883L_ID] = {
.channels = hmc5883_channels,
- .num_channels = ARRAY_SIZE(hmc5883_channels),
- .regval_to_sample_freq = hmc5883_regval_to_sample_freq,
- .regval_to_input_field_mga =
- hmc5883l_regval_to_input_field_mga,
+ .regval_to_samp_freq = hmc5883_regval_to_samp_freq,
.regval_to_nanoscale = hmc5883l_regval_to_nanoscale,
},
};
-static int hmc5843_detect(struct i2c_client *client,
- struct i2c_board_info *info)
+static int hmc5843_init(struct hmc5843_data *data)
{
- unsigned char id_str[HMC5843_ID_REG_LENGTH];
-
- if (client->addr != HMC5843_I2C_ADDRESS)
+ int ret;
+ u8 id[3];
+
+ ret = i2c_smbus_read_i2c_block_data(data->client, HMC5843_ID_REG,
+ sizeof(id), id);
+ if (ret < 0)
+ return ret;
+ if (id[0] != 'H' || id[1] != '4' || id[2] != '3') {
+ dev_err(&data->client->dev, "no HMC5843/5883/5883L sensor\n");
return -ENODEV;
+ }
- if (i2c_smbus_read_i2c_block_data(client, HMC5843_ID_REG_A,
- HMC5843_ID_REG_LENGTH, id_str)
- != HMC5843_ID_REG_LENGTH)
- return -ENODEV;
-
- if (0 != strncmp(id_str, HMC5843_ID_STRING, HMC5843_ID_REG_LENGTH))
- return -ENODEV;
-
- return 0;
-}
-
-/* Called when we have found a new HMC58X3 */
-static void hmc5843_init_client(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct iio_dev *indio_dev = i2c_get_clientdata(client);
- struct hmc5843_data *data = iio_priv(indio_dev);
-
- data->variant = &hmc5843_chip_info_tbl[id->driver_data];
- indio_dev->channels = data->variant->channels;
- indio_dev->num_channels = data->variant->num_channels;
- hmc5843_set_meas_conf(client, data->meas_conf);
- hmc5843_set_rate(client, data->rate);
- hmc5843_configure(client, data->operating_mode);
- i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_B, data->range);
- mutex_init(&data->lock);
-
- pr_info("%s initialized\n", id->name);
+ ret = hmc5843_set_meas_conf(data, HMC5843_MEAS_CONF_NORMAL);
+ if (ret < 0)
+ return ret;
+ ret = hmc5843_set_samp_freq(data, HMC5843_RATE_DEFAULT);
+ if (ret < 0)
+ return ret;
+ ret = hmc5843_set_range_gain(data, HMC5843_RANGE_GAIN_DEFAULT);
+ if (ret < 0)
+ return ret;
+ return hmc5843_set_mode(data, HMC5843_MODE_CONVERSION_CONTINUOUS);
}
static const struct iio_info hmc5843_info = {
.attrs = &hmc5843_group,
.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};
+
static int hmc5843_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct hmc5843_data *data;
struct iio_dev *indio_dev;
- int err = 0;
+ int ret;
- indio_dev = iio_device_alloc(sizeof(*data));
- if (indio_dev == NULL) {
- err = -ENOMEM;
- goto exit;
- }
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (indio_dev == NULL)
+ return -ENOMEM;
/* default settings at probe */
data = iio_priv(indio_dev);
- data->meas_conf = HMC5843_MEAS_CONF_NORMAL;
- data->range = HMC5843_RANGE_GAIN_DEFAULT;
- data->operating_mode = HMC5843_MODE_CONVERSION_CONTINUOUS;
+ data->client = client;
+ data->variant = &hmc5843_chip_info_tbl[id->driver_data];
+ mutex_init(&data->lock);
i2c_set_clientdata(client, indio_dev);
- hmc5843_init_client(client, id);
-
indio_dev->info = &hmc5843_info;
indio_dev->name = id->name;
indio_dev->dev.parent = &client->dev;
indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = data->variant->channels;
+ indio_dev->num_channels = 4;
+ indio_dev->available_scan_masks = hmc5843_scan_masks;
- err = iio_device_register(indio_dev);
- if (err)
- goto exit_free2;
+ ret = hmc5843_init(data);
+ if (ret < 0)
+ return ret;
+
+ ret = iio_triggered_buffer_setup(indio_dev, NULL,
+ hmc5843_trigger_handler, NULL);
+ if (ret < 0)
+ return ret;
+
+ ret = iio_device_register(indio_dev);
+ if (ret < 0)
+ goto buffer_cleanup;
return 0;
-exit_free2:
- iio_device_free(indio_dev);
-exit:
- return err;
+buffer_cleanup:
+ iio_triggered_buffer_cleanup(indio_dev);
+ return ret;
}
static int hmc5843_remove(struct i2c_client *client)
@@ -709,9 +590,10 @@ static int hmc5843_remove(struct i2c_client *client)
struct iio_dev *indio_dev = i2c_get_clientdata(client);
iio_device_unregister(indio_dev);
- /* sleep mode to save power */
- hmc5843_configure(client, HMC5843_MODE_SLEEP);
- iio_device_free(indio_dev);
+ iio_triggered_buffer_cleanup(indio_dev);
+
+ /* sleep mode to save power */
+ hmc5843_set_mode(iio_priv(indio_dev), HMC5843_MODE_SLEEP);
return 0;
}
@@ -719,19 +601,18 @@ static int hmc5843_remove(struct i2c_client *client)
#ifdef CONFIG_PM_SLEEP
static int hmc5843_suspend(struct device *dev)
{
- hmc5843_configure(to_i2c_client(dev), HMC5843_MODE_SLEEP);
- return 0;
+ struct hmc5843_data *data = iio_priv(i2c_get_clientdata(
+ to_i2c_client(dev)));
+
+ return hmc5843_set_mode(data, HMC5843_MODE_SLEEP);
}
static int hmc5843_resume(struct device *dev)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct iio_dev *indio_dev = i2c_get_clientdata(client);
- struct hmc5843_data *data = iio_priv(indio_dev);
-
- hmc5843_configure(client, data->operating_mode);
+ struct hmc5843_data *data = iio_priv(i2c_get_clientdata(
+ to_i2c_client(dev)));
- return 0;
+ return hmc5843_set_mode(data, HMC5843_MODE_CONVERSION_CONTINUOUS);
}
static SIMPLE_DEV_PM_OPS(hmc5843_pm_ops, hmc5843_suspend, hmc5843_resume);
@@ -748,19 +629,24 @@ static const struct i2c_device_id hmc5843_id[] = {
};
MODULE_DEVICE_TABLE(i2c, hmc5843_id);
+static const struct of_device_id hmc5843_of_match[] = {
+ { .compatible = "honeywell,hmc5843" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, hmc5843_of_match);
+
static struct i2c_driver hmc5843_driver = {
.driver = {
.name = "hmc5843",
.pm = HMC5843_PM_OPS,
+ .of_match_table = hmc5843_of_match,
},
.id_table = hmc5843_id,
.probe = hmc5843_probe,
.remove = hmc5843_remove,
- .detect = hmc5843_detect,
- .address_list = normal_i2c,
};
module_i2c_driver(hmc5843_driver);
-MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com");
+MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com>");
MODULE_DESCRIPTION("HMC5843/5883/5883L driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c
index e5943e2287c..00492cad7c5 100644
--- a/drivers/staging/iio/meter/ade7753.c
+++ b/drivers/staging/iio/meter/ade7753.c
@@ -86,7 +86,7 @@ static int ade7753_spi_read_reg_16(struct device *dev,
struct ade7753_state *st = iio_priv(indio_dev);
ssize_t ret;
- ret = spi_w8r16(st->us, ADE7753_READ_REG(reg_address));
+ ret = spi_w8r16be(st->us, ADE7753_READ_REG(reg_address));
if (ret < 0) {
dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
reg_address);
@@ -94,7 +94,6 @@ static int ade7753_spi_read_reg_16(struct device *dev,
}
*val = ret;
- *val = be16_to_cpup(val);
return 0;
}
@@ -186,9 +185,9 @@ static ssize_t ade7753_write_8bit(struct device *dev,
{
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
int ret;
- long val;
+ u8 val;
- ret = strict_strtol(buf, 10, &val);
+ ret = kstrtou8(buf, 10, &val);
if (ret)
goto error_ret;
ret = ade7753_spi_write_reg_8(dev, this_attr->address, val);
@@ -204,9 +203,9 @@ static ssize_t ade7753_write_16bit(struct device *dev,
{
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
int ret;
- long val;
+ u16 val;
- ret = strict_strtol(buf, 10, &val);
+ ret = kstrtou16(buf, 10, &val);
if (ret)
goto error_ret;
ret = ade7753_spi_write_reg_16(dev, this_attr->address, val);
@@ -225,21 +224,6 @@ static int ade7753_reset(struct device *dev)
return ade7753_spi_write_reg_16(dev, ADE7753_MODE, val);
}
-static ssize_t ade7753_write_reset(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- if (len < 1)
- return -1;
- switch (buf[0]) {
- case '1':
- case 'y':
- case 'Y':
- return ade7753_reset(dev);
- }
- return -1;
-}
-
static IIO_DEV_ATTR_AENERGY(ade7753_read_24bit, ADE7753_AENERGY);
static IIO_DEV_ATTR_LAENERGY(ade7753_read_24bit, ADE7753_LAENERGY);
static IIO_DEV_ATTR_VAENERGY(ade7753_read_24bit, ADE7753_VAENERGY);
@@ -414,11 +398,11 @@ static ssize_t ade7753_write_frequency(struct device *dev,
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7753_state *st = iio_priv(indio_dev);
- unsigned long val;
+ u16 val;
int ret;
u16 reg, t;
- ret = strict_strtol(buf, 10, &val);
+ ret = kstrtou16(buf, 10, &val);
if (ret)
return ret;
if (val == 0)
@@ -458,8 +442,6 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
ade7753_read_frequency,
ade7753_write_frequency);
-static IIO_DEV_ATTR_RESET(ade7753_write_reset);
-
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("27900 14000 7000 3500");
static struct attribute *ade7753_attributes[] = {
@@ -468,7 +450,6 @@ static struct attribute *ade7753_attributes[] = {
&iio_const_attr_in_temp_scale.dev_attr.attr,
&iio_dev_attr_sampling_frequency.dev_attr.attr,
&iio_const_attr_sampling_frequency_available.dev_attr.attr,
- &iio_dev_attr_reset.dev_attr.attr,
&iio_dev_attr_phcal.dev_attr.attr,
&iio_dev_attr_cfden.dev_attr.attr,
&iio_dev_attr_aenergy.dev_attr.attr,
@@ -515,11 +496,9 @@ static int ade7753_probe(struct spi_device *spi)
struct iio_dev *indio_dev;
/* setup the industrialio driver allocated elements */
- indio_dev = iio_device_alloc(sizeof(*st));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (!indio_dev)
+ return -ENOMEM;
/* this is only used for removal purposes */
spi_set_drvdata(spi, indio_dev);
@@ -535,19 +514,13 @@ static int ade7753_probe(struct spi_device *spi)
/* Get the device into a sane initial state */
ret = ade7753_initial_setup(indio_dev);
if (ret)
- goto error_free_dev;
+ return ret;
ret = iio_device_register(indio_dev);
if (ret)
- goto error_free_dev;
+ return ret;
return 0;
-
-error_free_dev:
- iio_device_free(indio_dev);
-
-error_ret:
- return ret;
}
/* fixme, confirm ordering in this function */
@@ -557,7 +530,6 @@ static int ade7753_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
ade7753_stop_device(&indio_dev->dev);
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c
index 7b6503bf9a7..e0aa13ab365 100644
--- a/drivers/staging/iio/meter/ade7754.c
+++ b/drivers/staging/iio/meter/ade7754.c
@@ -86,7 +86,7 @@ static int ade7754_spi_read_reg_16(struct device *dev,
struct ade7754_state *st = iio_priv(indio_dev);
int ret;
- ret = spi_w8r16(st->us, ADE7754_READ_REG(reg_address));
+ ret = spi_w8r16be(st->us, ADE7754_READ_REG(reg_address));
if (ret < 0) {
dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
reg_address);
@@ -94,7 +94,6 @@ static int ade7754_spi_read_reg_16(struct device *dev,
}
*val = ret;
- *val = be16_to_cpup(val);
return 0;
}
@@ -186,9 +185,9 @@ static ssize_t ade7754_write_8bit(struct device *dev,
{
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
int ret;
- long val;
+ u8 val;
- ret = strict_strtol(buf, 10, &val);
+ ret = kstrtou8(buf, 10, &val);
if (ret)
goto error_ret;
ret = ade7754_spi_write_reg_8(dev, this_attr->address, val);
@@ -204,9 +203,9 @@ static ssize_t ade7754_write_16bit(struct device *dev,
{
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
int ret;
- long val;
+ u16 val;
- ret = strict_strtol(buf, 10, &val);
+ ret = kstrtou16(buf, 10, &val);
if (ret)
goto error_ret;
ret = ade7754_spi_write_reg_16(dev, this_attr->address, val);
@@ -224,22 +223,6 @@ static int ade7754_reset(struct device *dev)
return ade7754_spi_write_reg_8(dev, ADE7754_OPMODE, val);
}
-
-static ssize_t ade7754_write_reset(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- if (len < 1)
- return -1;
- switch (buf[0]) {
- case '1':
- case 'y':
- case 'Y':
- return ade7754_reset(dev);
- }
- return -1;
-}
-
static IIO_DEV_ATTR_AENERGY(ade7754_read_24bit, ADE7754_AENERGY);
static IIO_DEV_ATTR_LAENERGY(ade7754_read_24bit, ADE7754_LAENERGY);
static IIO_DEV_ATTR_VAENERGY(ade7754_read_24bit, ADE7754_VAENERGY);
@@ -435,11 +418,11 @@ static ssize_t ade7754_write_frequency(struct device *dev,
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7754_state *st = iio_priv(indio_dev);
- unsigned long val;
+ u16 val;
int ret;
u8 reg, t;
- ret = strict_strtol(buf, 10, &val);
+ ret = kstrtou16(buf, 10, &val);
if (ret)
return ret;
if (val == 0)
@@ -478,8 +461,6 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
ade7754_read_frequency,
ade7754_write_frequency);
-static IIO_DEV_ATTR_RESET(ade7754_write_reset);
-
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("26000 13000 65000 33000");
static struct attribute *ade7754_attributes[] = {
@@ -488,7 +469,6 @@ static struct attribute *ade7754_attributes[] = {
&iio_const_attr_in_temp_scale.dev_attr.attr,
&iio_dev_attr_sampling_frequency.dev_attr.attr,
&iio_const_attr_sampling_frequency_available.dev_attr.attr,
- &iio_dev_attr_reset.dev_attr.attr,
&iio_dev_attr_aenergy.dev_attr.attr,
&iio_dev_attr_laenergy.dev_attr.attr,
&iio_dev_attr_vaenergy.dev_attr.attr,
@@ -539,11 +519,9 @@ static int ade7754_probe(struct spi_device *spi)
struct iio_dev *indio_dev;
/* setup the industrialio driver allocated elements */
- indio_dev = iio_device_alloc(sizeof(*st));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (!indio_dev)
+ return -ENOMEM;
/* this is only used for removal purposes */
spi_set_drvdata(spi, indio_dev);
@@ -559,18 +537,12 @@ static int ade7754_probe(struct spi_device *spi)
/* Get the device into a sane initial state */
ret = ade7754_initial_setup(indio_dev);
if (ret)
- goto error_free_dev;
+ return ret;
ret = iio_device_register(indio_dev);
if (ret)
- goto error_free_dev;
+ return ret;
return 0;
-
-error_free_dev:
- iio_device_free(indio_dev);
-
-error_ret:
- return ret;
}
/* fixme, confirm ordering in this function */
@@ -580,7 +552,6 @@ static int ade7754_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
ade7754_stop_device(&indio_dev->dev);
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c
index 8f5bcfab356..cba183e2483 100644
--- a/drivers/staging/iio/meter/ade7758_core.c
+++ b/drivers/staging/iio/meter/ade7758_core.c
@@ -269,9 +269,9 @@ static ssize_t ade7758_write_8bit(struct device *dev,
{
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
int ret;
- long val;
+ u8 val;
- ret = strict_strtol(buf, 10, &val);
+ ret = kstrtou8(buf, 10, &val);
if (ret)
goto error_ret;
ret = ade7758_spi_write_reg_8(dev, this_attr->address, val);
@@ -287,9 +287,9 @@ static ssize_t ade7758_write_16bit(struct device *dev,
{
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
int ret;
- long val;
+ u16 val;
- ret = strict_strtol(buf, 10, &val);
+ ret = kstrtou16(buf, 10, &val);
if (ret)
goto error_ret;
ret = ade7758_spi_write_reg_16(dev, this_attr->address, val);
@@ -313,21 +313,6 @@ static int ade7758_reset(struct device *dev)
return ret;
}
-static ssize_t ade7758_write_reset(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- if (len < 1)
- return -1;
- switch (buf[0]) {
- case '1':
- case 'y':
- case 'Y':
- return ade7758_reset(dev);
- }
- return len;
-}
-
static IIO_DEV_ATTR_VPEAK(S_IWUSR | S_IRUGO,
ade7758_read_8bit,
ade7758_write_8bit,
@@ -517,11 +502,11 @@ static ssize_t ade7758_write_frequency(struct device *dev,
size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- unsigned long val;
+ u16 val;
int ret;
u8 reg, t;
- ret = strict_strtol(buf, 10, &val);
+ ret = kstrtou16(buf, 10, &val);
if (ret)
return ret;
@@ -591,8 +576,6 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
ade7758_read_frequency,
ade7758_write_frequency);
-static IIO_DEV_ATTR_RESET(ade7758_write_reset);
-
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("26040 13020 6510 3255");
static struct attribute *ade7758_attributes[] = {
@@ -601,7 +584,6 @@ static struct attribute *ade7758_attributes[] = {
&iio_const_attr_in_temp_scale.dev_attr.attr,
&iio_dev_attr_sampling_frequency.dev_attr.attr,
&iio_const_attr_sampling_frequency_available.dev_attr.attr,
- &iio_dev_attr_reset.dev_attr.attr,
&iio_dev_attr_awatthr.dev_attr.attr,
&iio_dev_attr_bwatthr.dev_attr.attr,
&iio_dev_attr_cwatthr.dev_attr.attr,
@@ -867,12 +849,11 @@ static int ade7758_probe(struct spi_device *spi)
{
int ret;
struct ade7758_state *st;
- struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
+ struct iio_dev *indio_dev;
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (!indio_dev)
+ return -ENOMEM;
st = iio_priv(indio_dev);
/* this is only used for removal purposes */
@@ -880,10 +861,8 @@ static int ade7758_probe(struct spi_device *spi)
/* Allocate the comms buffers */
st->rx = kcalloc(ADE7758_MAX_RX, sizeof(*st->rx), GFP_KERNEL);
- if (st->rx == NULL) {
- ret = -ENOMEM;
- goto error_free_dev;
- }
+ if (!st->rx)
+ return -ENOMEM;
st->tx = kcalloc(ADE7758_MAX_TX, sizeof(*st->tx), GFP_KERNEL);
if (st->tx == NULL) {
ret = -ENOMEM;
@@ -938,9 +917,6 @@ error_free_tx:
kfree(st->tx);
error_free_rx:
kfree(st->rx);
-error_free_dev:
- iio_device_free(indio_dev);
-error_ret:
return ret;
}
@@ -957,8 +933,6 @@ static int ade7758_remove(struct spi_device *spi)
kfree(st->tx);
kfree(st->rx);
- iio_device_free(indio_dev);
-
return 0;
}
diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c
index b29e2d5d993..c0accf8cce9 100644
--- a/drivers/staging/iio/meter/ade7758_ring.c
+++ b/drivers/staging/iio/meter/ade7758_ring.c
@@ -54,7 +54,7 @@ out:
return ret;
}
-/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
+/* Whilst this makes a lot of calls to iio_sw_ring functions - it is too device
* specific to be rolled into the core.
*/
static irqreturn_t ade7758_trigger_handler(int irq, void *p)
@@ -69,11 +69,7 @@ static irqreturn_t ade7758_trigger_handler(int irq, void *p)
if (ade7758_spi_read_burst(indio_dev) >= 0)
*dat32 = get_unaligned_be32(&st->rx_buf[5]) & 0xFFFFFF;
- /* Guaranteed to be aligned with 8 byte boundary */
- if (indio_dev->scan_timestamp)
- dat64[1] = pf->timestamp;
-
- iio_push_to_buffers(indio_dev, (u8 *)dat64);
+ iio_push_to_buffers_with_timestamp(indio_dev, dat64, pf->timestamp);
iio_trigger_notify_done(indio_dev->trig);
@@ -91,15 +87,10 @@ static int ade7758_ring_preenable(struct iio_dev *indio_dev)
{
struct ade7758_state *st = iio_priv(indio_dev);
unsigned channel;
- int ret;
if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
return -EINVAL;
- ret = iio_sw_buffer_preenable(indio_dev);
- if (ret < 0)
- return ret;
-
channel = find_first_bit(indio_dev->active_scan_mask,
indio_dev->masklength);
@@ -125,14 +116,17 @@ void ade7758_unconfigure_ring(struct iio_dev *indio_dev)
int ade7758_configure_ring(struct iio_dev *indio_dev)
{
struct ade7758_state *st = iio_priv(indio_dev);
+ struct iio_buffer *buffer;
int ret = 0;
- indio_dev->buffer = iio_kfifo_allocate(indio_dev);
- if (!indio_dev->buffer) {
+ buffer = iio_kfifo_allocate(indio_dev);
+ if (!buffer) {
ret = -ENOMEM;
return ret;
}
+ iio_device_attach_buffer(indio_dev, buffer);
+
indio_dev->setup_ops = &ade7758_ring_setup_ops;
indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c
index 17dc373e108..ea0c9debf8b 100644
--- a/drivers/staging/iio/meter/ade7759.c
+++ b/drivers/staging/iio/meter/ade7759.c
@@ -86,7 +86,7 @@ static int ade7759_spi_read_reg_16(struct device *dev,
struct ade7759_state *st = iio_priv(indio_dev);
int ret;
- ret = spi_w8r16(st->us, ADE7759_READ_REG(reg_address));
+ ret = spi_w8r16be(st->us, ADE7759_READ_REG(reg_address));
if (ret < 0) {
dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
reg_address);
@@ -94,7 +94,6 @@ static int ade7759_spi_read_reg_16(struct device *dev,
}
*val = ret;
- *val = be16_to_cpup(val);
return 0;
}
@@ -185,9 +184,9 @@ static ssize_t ade7759_write_8bit(struct device *dev,
{
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
int ret;
- long val;
+ u8 val;
- ret = strict_strtol(buf, 10, &val);
+ ret = kstrtou8(buf, 10, &val);
if (ret)
goto error_ret;
ret = ade7759_spi_write_reg_8(dev, this_attr->address, val);
@@ -203,9 +202,9 @@ static ssize_t ade7759_write_16bit(struct device *dev,
{
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
int ret;
- long val;
+ u16 val;
- ret = strict_strtol(buf, 10, &val);
+ ret = kstrtou16(buf, 10, &val);
if (ret)
goto error_ret;
ret = ade7759_spi_write_reg_16(dev, this_attr->address, val);
@@ -229,21 +228,6 @@ static int ade7759_reset(struct device *dev)
return ret;
}
-static ssize_t ade7759_write_reset(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- if (len < 1)
- return -1;
- switch (buf[0]) {
- case '1':
- case 'y':
- case 'Y':
- return ade7759_reset(dev);
- }
- return -1;
-}
-
static IIO_DEV_ATTR_AENERGY(ade7759_read_40bit, ADE7759_AENERGY);
static IIO_DEV_ATTR_CFDEN(S_IWUSR | S_IRUGO,
ade7759_read_16bit,
@@ -375,11 +359,11 @@ static ssize_t ade7759_write_frequency(struct device *dev,
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7759_state *st = iio_priv(indio_dev);
- unsigned long val;
+ u16 val;
int ret;
u16 reg, t;
- ret = strict_strtol(buf, 10, &val);
+ ret = kstrtou16(buf, 10, &val);
if (ret)
return ret;
if (val == 0)
@@ -418,8 +402,6 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
ade7759_read_frequency,
ade7759_write_frequency);
-static IIO_DEV_ATTR_RESET(ade7759_write_reset);
-
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("27900 14000 7000 3500");
static struct attribute *ade7759_attributes[] = {
@@ -428,7 +410,6 @@ static struct attribute *ade7759_attributes[] = {
&iio_const_attr_in_temp_scale.dev_attr.attr,
&iio_dev_attr_sampling_frequency.dev_attr.attr,
&iio_const_attr_sampling_frequency_available.dev_attr.attr,
- &iio_dev_attr_reset.dev_attr.attr,
&iio_dev_attr_phcal.dev_attr.attr,
&iio_dev_attr_cfden.dev_attr.attr,
&iio_dev_attr_aenergy.dev_attr.attr,
@@ -462,11 +443,9 @@ static int ade7759_probe(struct spi_device *spi)
struct iio_dev *indio_dev;
/* setup the industrialio driver allocated elements */
- indio_dev = iio_device_alloc(sizeof(*st));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (!indio_dev)
+ return -ENOMEM;
/* this is only used for removal purposes */
spi_set_drvdata(spi, indio_dev);
@@ -481,18 +460,13 @@ static int ade7759_probe(struct spi_device *spi)
/* Get the device into a sane initial state */
ret = ade7759_initial_setup(indio_dev);
if (ret)
- goto error_free_dev;
+ return ret;
ret = iio_device_register(indio_dev);
if (ret)
- goto error_free_dev;
+ return ret;
return 0;
-
-error_free_dev:
- iio_device_free(indio_dev);
-error_ret:
- return ret;
}
/* fixme, confirm ordering in this function */
@@ -502,7 +476,6 @@ static int ade7759_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
ade7759_stop_device(&indio_dev->dev);
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/meter/ade7854-i2c.c b/drivers/staging/iio/meter/ade7854-i2c.c
index db9ef6c86c1..5b33c7f1aa9 100644
--- a/drivers/staging/iio/meter/ade7854-i2c.c
+++ b/drivers/staging/iio/meter/ade7854-i2c.c
@@ -208,7 +208,7 @@ static int ade7854_i2c_probe(struct i2c_client *client,
struct ade7854_state *st;
struct iio_dev *indio_dev;
- indio_dev = iio_device_alloc(sizeof(*st));
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
st = iio_priv(indio_dev);
@@ -225,8 +225,6 @@ static int ade7854_i2c_probe(struct i2c_client *client,
st->irq = client->irq;
ret = ade7854_probe(indio_dev, &client->dev);
- if (ret)
- iio_device_free(indio_dev);
return ret;
}
diff --git a/drivers/staging/iio/meter/ade7854-spi.c b/drivers/staging/iio/meter/ade7854-spi.c
index a802cf2491d..94f73bbbc0f 100644
--- a/drivers/staging/iio/meter/ade7854-spi.c
+++ b/drivers/staging/iio/meter/ade7854-spi.c
@@ -278,7 +278,7 @@ static int ade7854_spi_probe(struct spi_device *spi)
struct ade7854_state *st;
struct iio_dev *indio_dev;
- indio_dev = iio_device_alloc(sizeof(*st));
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
st = iio_priv(indio_dev);
@@ -296,10 +296,8 @@ static int ade7854_spi_probe(struct spi_device *spi)
ret = ade7854_probe(indio_dev, &spi->dev);
- if (ret)
- iio_device_free(indio_dev);
- return 0;
+ return ret;
}
static int ade7854_spi_remove(struct spi_device *spi)
diff --git a/drivers/staging/iio/meter/ade7854.c b/drivers/staging/iio/meter/ade7854.c
index c642da84842..d620bbd603a 100644
--- a/drivers/staging/iio/meter/ade7854.c
+++ b/drivers/staging/iio/meter/ade7854.c
@@ -100,9 +100,9 @@ static ssize_t ade7854_write_8bit(struct device *dev,
struct ade7854_state *st = iio_priv(indio_dev);
int ret;
- long val;
+ u8 val;
- ret = strict_strtol(buf, 10, &val);
+ ret = kstrtou8(buf, 10, &val);
if (ret)
goto error_ret;
ret = st->write_reg_8(dev, this_attr->address, val);
@@ -121,9 +121,9 @@ static ssize_t ade7854_write_16bit(struct device *dev,
struct ade7854_state *st = iio_priv(indio_dev);
int ret;
- long val;
+ u16 val;
- ret = strict_strtol(buf, 10, &val);
+ ret = kstrtou16(buf, 10, &val);
if (ret)
goto error_ret;
ret = st->write_reg_16(dev, this_attr->address, val);
@@ -142,9 +142,9 @@ static ssize_t ade7854_write_24bit(struct device *dev,
struct ade7854_state *st = iio_priv(indio_dev);
int ret;
- long val;
+ u32 val;
- ret = strict_strtol(buf, 10, &val);
+ ret = kstrtou32(buf, 10, &val);
if (ret)
goto error_ret;
ret = st->write_reg_24(dev, this_attr->address, val);
@@ -163,9 +163,9 @@ static ssize_t ade7854_write_32bit(struct device *dev,
struct ade7854_state *st = iio_priv(indio_dev);
int ret;
- long val;
+ u32 val;
- ret = strict_strtol(buf, 10, &val);
+ ret = kstrtou32(buf, 10, &val);
if (ret)
goto error_ret;
ret = st->write_reg_32(dev, this_attr->address, val);
@@ -186,22 +186,6 @@ static int ade7854_reset(struct device *dev)
return st->write_reg_16(dev, ADE7854_CONFIG, val);
}
-
-static ssize_t ade7854_write_reset(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- if (len < 1)
- return -1;
- switch (buf[0]) {
- case '1':
- case 'y':
- case 'Y':
- return ade7854_reset(dev);
- }
- return -1;
-}
-
static IIO_DEV_ATTR_AIGAIN(S_IWUSR | S_IRUGO,
ade7854_read_24bit,
ade7854_write_24bit,
@@ -468,8 +452,6 @@ err_ret:
return ret;
}
-static IIO_DEV_ATTR_RESET(ade7854_write_reset);
-
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("8000");
static IIO_CONST_ATTR(name, "ade7854");
@@ -515,7 +497,6 @@ static struct attribute *ade7854_attributes[] = {
&iio_dev_attr_bvahr.dev_attr.attr,
&iio_dev_attr_cvahr.dev_attr.attr,
&iio_const_attr_sampling_frequency_available.dev_attr.attr,
- &iio_dev_attr_reset.dev_attr.attr,
&iio_const_attr_name.dev_attr.attr,
&iio_dev_attr_vpeak.dev_attr.attr,
&iio_dev_attr_ipeak.dev_attr.attr,
@@ -569,7 +550,7 @@ int ade7854_probe(struct iio_dev *indio_dev, struct device *dev)
ret = iio_device_register(indio_dev);
if (ret)
- goto error_free_dev;
+ return ret;
/* Get the device into a sane initial state */
ret = ade7854_initial_setup(indio_dev);
@@ -580,9 +561,6 @@ int ade7854_probe(struct iio_dev *indio_dev, struct device *dev)
error_unreg_dev:
iio_device_unregister(indio_dev);
-error_free_dev:
- iio_device_free(indio_dev);
-
return ret;
}
EXPORT_SYMBOL(ade7854_probe);
@@ -590,7 +568,6 @@ EXPORT_SYMBOL(ade7854_probe);
int ade7854_remove(struct iio_dev *indio_dev)
{
iio_device_unregister(indio_dev);
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/staging/iio/resolver/ad2s1200.c
index 71221161aa6..017d2f8379b 100644
--- a/drivers/staging/iio/resolver/ad2s1200.c
+++ b/drivers/staging/iio/resolver/ad2s1200.c
@@ -70,6 +70,7 @@ static int ad2s1200_read_raw(struct iio_dev *indio_dev,
vel = (((s16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4);
vel = (vel << 4) >> 4;
*val = vel;
+ break;
default:
mutex_unlock(&st->lock);
return -EINVAL;
@@ -106,17 +107,18 @@ static int ad2s1200_probe(struct spi_device *spi)
int pn, ret = 0;
unsigned short *pins = spi->dev.platform_data;
- for (pn = 0; pn < AD2S1200_PN; pn++)
- if (gpio_request_one(pins[pn], GPIOF_DIR_OUT, DRV_NAME)) {
- pr_err("%s: request gpio pin %d failed\n",
- DRV_NAME, pins[pn]);
- goto error_ret;
+ for (pn = 0; pn < AD2S1200_PN; pn++) {
+ ret = devm_gpio_request_one(&spi->dev, pins[pn], GPIOF_DIR_OUT,
+ DRV_NAME);
+ if (ret) {
+ dev_err(&spi->dev, "request gpio pin %d failed\n",
+ pins[pn]);
+ return ret;
}
- indio_dev = iio_device_alloc(sizeof(*st));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
}
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (!indio_dev)
+ return -ENOMEM;
spi_set_drvdata(spi, indio_dev);
st = iio_priv(indio_dev);
mutex_init(&st->lock);
@@ -131,30 +133,15 @@ static int ad2s1200_probe(struct spi_device *spi)
indio_dev->num_channels = ARRAY_SIZE(ad2s1200_channels);
indio_dev->name = spi_get_device_id(spi)->name;
- ret = iio_device_register(indio_dev);
+ ret = devm_iio_device_register(&spi->dev, indio_dev);
if (ret)
- goto error_free_dev;
+ return ret;
spi->max_speed_hz = AD2S1200_HZ;
spi->mode = SPI_MODE_3;
spi_setup(spi);
return 0;
-
-error_free_dev:
- iio_device_free(indio_dev);
-error_ret:
- for (--pn; pn >= 0; pn--)
- gpio_free(pins[pn]);
- return ret;
-}
-
-static int ad2s1200_remove(struct spi_device *spi)
-{
- iio_device_unregister(spi_get_drvdata(spi));
- iio_device_free(spi_get_drvdata(spi));
-
- return 0;
}
static const struct spi_device_id ad2s1200_id[] = {
@@ -170,7 +157,6 @@ static struct spi_driver ad2s1200_driver = {
.owner = THIS_MODULE,
},
.probe = ad2s1200_probe,
- .remove = ad2s1200_remove,
.id_table = ad2s1200_id,
};
module_spi_driver(ad2s1200_driver);
diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index 0d3356d4b7d..7fbaba41c87 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -192,21 +192,6 @@ static inline int ad2s1210_soft_reset(struct ad2s1210_state *st)
return ad2s1210_config_write(st, 0x0);
}
-static ssize_t ad2s1210_store_softreset(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
- int ret;
-
- mutex_lock(&st->lock);
- ret = ad2s1210_soft_reset(st);
- mutex_unlock(&st->lock);
-
- return ret < 0 ? ret : len;
-}
-
static ssize_t ad2s1210_show_fclkin(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -221,10 +206,10 @@ static ssize_t ad2s1210_store_fclkin(struct device *dev,
size_t len)
{
struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
- unsigned long fclkin;
+ unsigned int fclkin;
int ret;
- ret = strict_strtoul(buf, 10, &fclkin);
+ ret = kstrtouint(buf, 10, &fclkin);
if (ret)
return ret;
if (fclkin < AD2S1210_MIN_CLKIN || fclkin > AD2S1210_MAX_CLKIN) {
@@ -258,10 +243,10 @@ static ssize_t ad2s1210_store_fexcit(struct device *dev,
const char *buf, size_t len)
{
struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
- unsigned long fexcit;
+ unsigned int fexcit;
int ret;
- ret = strict_strtoul(buf, 10, &fexcit);
+ ret = kstrtouint(buf, 10, &fexcit);
if (ret < 0)
return ret;
if (fexcit < AD2S1210_MIN_EXCIT || fexcit > AD2S1210_MAX_EXCIT) {
@@ -297,11 +282,11 @@ static ssize_t ad2s1210_store_control(struct device *dev,
const char *buf, size_t len)
{
struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
- unsigned long udata;
+ unsigned char udata;
unsigned char data;
int ret;
- ret = strict_strtoul(buf, 16, &udata);
+ ret = kstrtou8(buf, 16, &udata);
if (ret)
return -EINVAL;
@@ -327,7 +312,7 @@ static ssize_t ad2s1210_store_control(struct device *dev,
if (st->pdata->gpioin) {
data = ad2s1210_read_resolution_pin(st);
if (data != st->resolution)
- pr_warning("ad2s1210: resolution settings not match\n");
+ pr_warn("ad2s1210: resolution settings not match\n");
} else
ad2s1210_set_resolution_pin(st);
@@ -352,10 +337,10 @@ static ssize_t ad2s1210_store_resolution(struct device *dev,
{
struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
unsigned char data;
- unsigned long udata;
+ unsigned char udata;
int ret;
- ret = strict_strtoul(buf, 10, &udata);
+ ret = kstrtou8(buf, 10, &udata);
if (ret || udata < 10 || udata > 16) {
pr_err("ad2s1210: resolution out of range\n");
return -EINVAL;
@@ -387,7 +372,7 @@ static ssize_t ad2s1210_store_resolution(struct device *dev,
if (st->pdata->gpioin) {
data = ad2s1210_read_resolution_pin(st);
if (data != st->resolution)
- pr_warning("ad2s1210: resolution settings not match\n");
+ pr_warn("ad2s1210: resolution settings not match\n");
} else
ad2s1210_set_resolution_pin(st);
ret = len;
@@ -453,11 +438,11 @@ static ssize_t ad2s1210_store_reg(struct device *dev,
struct device_attribute *attr, const char *buf, size_t len)
{
struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
- unsigned long data;
+ unsigned char data;
int ret;
struct iio_dev_attr *iattr = to_iio_dev_attr(attr);
- ret = strict_strtoul(buf, 10, &data);
+ ret = kstrtou8(buf, 10, &data);
if (ret)
return -EINVAL;
mutex_lock(&st->lock);
@@ -536,8 +521,6 @@ error_ret:
return ret;
}
-static IIO_DEVICE_ATTR(reset, S_IWUSR,
- NULL, ad2s1210_store_softreset, 0);
static IIO_DEVICE_ATTR(fclkin, S_IRUGO | S_IWUSR,
ad2s1210_show_fclkin, ad2s1210_store_fclkin, 0);
static IIO_DEVICE_ATTR(fexcit, S_IRUGO | S_IWUSR,
@@ -587,7 +570,6 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
};
static struct attribute *ad2s1210_attributes[] = {
- &iio_dev_attr_reset.dev_attr.attr,
&iio_dev_attr_fclkin.dev_attr.attr,
&iio_dev_attr_fexcit.dev_attr.attr,
&iio_dev_attr_control.dev_attr.attr,
@@ -687,16 +669,14 @@ static int ad2s1210_probe(struct spi_device *spi)
if (spi->dev.platform_data == NULL)
return -EINVAL;
- indio_dev = iio_device_alloc(sizeof(*st));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (!indio_dev)
+ return -ENOMEM;
st = iio_priv(indio_dev);
st->pdata = spi->dev.platform_data;
ret = ad2s1210_setup_gpios(st);
if (ret < 0)
- goto error_free_dev;
+ return ret;
spi_set_drvdata(spi, indio_dev);
@@ -727,9 +707,6 @@ static int ad2s1210_probe(struct spi_device *spi)
error_free_gpios:
ad2s1210_free_gpios(st);
-error_free_dev:
- iio_device_free(indio_dev);
-error_ret:
return ret;
}
@@ -739,7 +716,6 @@ static int ad2s1210_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
ad2s1210_free_gpios(iio_priv(indio_dev));
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/resolver/ad2s90.c b/drivers/staging/iio/resolver/ad2s90.c
index 40b825286d4..e24c5890652 100644
--- a/drivers/staging/iio/resolver/ad2s90.c
+++ b/drivers/staging/iio/resolver/ad2s90.c
@@ -64,11 +64,9 @@ static int ad2s90_probe(struct spi_device *spi)
struct ad2s90_state *st;
int ret = 0;
- indio_dev = iio_device_alloc(sizeof(*st));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (!indio_dev)
+ return -ENOMEM;
st = iio_priv(indio_dev);
spi_set_drvdata(spi, indio_dev);
@@ -83,7 +81,7 @@ static int ad2s90_probe(struct spi_device *spi)
ret = iio_device_register(indio_dev);
if (ret)
- goto error_free_dev;
+ return ret;
/* need 600ns between CS and the first falling edge of SCLK */
spi->max_speed_hz = 830000;
@@ -91,17 +89,11 @@ static int ad2s90_probe(struct spi_device *spi)
spi_setup(spi);
return 0;
-
-error_free_dev:
- iio_device_free(indio_dev);
-error_ret:
- return ret;
}
static int ad2s90_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
- iio_device_free(spi_get_drvdata(spi));
return 0;
}
diff --git a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c
index 38a158b77b1..26e1ca0b780 100644
--- a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c
+++ b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c
@@ -83,32 +83,28 @@ static ssize_t iio_bfin_tmr_frequency_store(struct device *dev,
{
struct iio_trigger *trig = to_iio_trigger(dev);
struct bfin_tmr_state *st = iio_trigger_get_drvdata(trig);
- unsigned long val;
+ unsigned int val;
bool enabled;
int ret;
- ret = strict_strtoul(buf, 10, &val);
+ ret = kstrtouint(buf, 10, &val);
if (ret)
- goto error_ret;
+ return ret;
- if (val > 100000) {
- ret = -EINVAL;
- goto error_ret;
- }
+ if (val > 100000)
+ return -EINVAL;
enabled = get_enabled_gptimers() & st->t->bit;
if (enabled)
disable_gptimers(st->t->bit);
- if (!val)
- goto error_ret;
+ if (val == 0)
+ return count;
val = get_sclk() / val;
- if (val <= 4 || val <= st->duty) {
- ret = -EINVAL;
- goto error_ret;
- }
+ if (val <= 4 || val <= st->duty)
+ return -EINVAL;
set_gptimer_period(st->t->id, val);
set_gptimer_pwidth(st->t->id, val - st->duty);
@@ -116,8 +112,7 @@ static ssize_t iio_bfin_tmr_frequency_store(struct device *dev,
if (enabled)
enable_gptimers(st->t->bit);
-error_ret:
- return ret ? ret : count;
+ return count;
}
static ssize_t iio_bfin_tmr_frequency_show(struct device *dev,
diff --git a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
index 79695974b1d..38ecb4bb6e4 100644
--- a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
+++ b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
@@ -33,7 +33,8 @@ static int iio_trig_periodic_rtc_set_state(struct iio_trigger *trig, bool state)
struct iio_prtc_trigger_info *trig_info = iio_trigger_get_drvdata(trig);
if (trig_info->frequency == 0)
return -EINVAL;
- printk(KERN_INFO "trigger frequency is %d\n", trig_info->frequency);
+ dev_info(&trig_info->rtc->dev, "trigger frequency is %d\n",
+ trig_info->frequency);
return rtc_irq_set_state(trig_info->rtc, &trig_info->task, state);
}
@@ -53,10 +54,10 @@ static ssize_t iio_trig_periodic_write_freq(struct device *dev,
{
struct iio_trigger *trig = to_iio_trigger(dev);
struct iio_prtc_trigger_info *trig_info = iio_trigger_get_drvdata(trig);
- unsigned long val;
+ int val;
int ret;
- ret = strict_strtoul(buf, 10, &val);
+ ret = kstrtoint(buf, 10, &val);
if (ret)
goto error_ret;