aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/iio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/iio')
-rw-r--r--drivers/staging/iio/Documentation/generic_buffer.c9
-rw-r--r--drivers/staging/iio/Documentation/iio_event_monitor.c8
-rw-r--r--drivers/staging/iio/Documentation/iio_utils.h6
-rw-r--r--drivers/staging/iio/Documentation/sysfs-bus-iio-trigger-sysfs11
-rw-r--r--drivers/staging/iio/Documentation/trigger.txt2
-rw-r--r--drivers/staging/iio/Kconfig9
-rw-r--r--drivers/staging/iio/accel/adis16201_core.c14
-rw-r--r--drivers/staging/iio/accel/adis16203_core.c11
-rw-r--r--drivers/staging/iio/accel/adis16204_core.c12
-rw-r--r--drivers/staging/iio/accel/adis16209_core.c18
-rw-r--r--drivers/staging/iio/accel/adis16240_core.c12
-rw-r--r--drivers/staging/iio/accel/lis3l02dq_ring.c2
-rw-r--r--drivers/staging/iio/accel/sca3000_ring.c6
-rw-r--r--drivers/staging/iio/adc/Kconfig9
-rw-r--r--drivers/staging/iio/adc/Makefile1
-rw-r--r--drivers/staging/iio/adc/ad7291.c580
-rw-r--r--drivers/staging/iio/adc/ad7291.h12
-rw-r--r--drivers/staging/iio/adc/ad7606_par.c37
-rw-r--r--drivers/staging/iio/adc/mxs-lradc.c14
-rw-r--r--drivers/staging/iio/frequency/ad9832.c16
-rw-r--r--drivers/staging/iio/frequency/ad9850.c6
-rw-r--r--drivers/staging/iio/iio_simple_dummy.c2
-rw-r--r--drivers/staging/iio/light/tsl2x7x_core.c8
-rw-r--r--drivers/staging/iio/magnetometer/Kconfig30
-rw-r--r--drivers/staging/iio/magnetometer/Makefile4
-rw-r--r--drivers/staging/iio/magnetometer/hmc5843.h59
-rw-r--r--drivers/staging/iio/magnetometer/hmc5843_core.c (renamed from drivers/staging/iio/magnetometer/hmc5843.c)266
-rw-r--r--drivers/staging/iio/magnetometer/hmc5843_i2c.c104
-rw-r--r--drivers/staging/iio/magnetometer/hmc5843_spi.c100
-rw-r--r--drivers/staging/iio/meter/ade7758_trigger.c2
-rw-r--r--drivers/staging/iio/trigger/iio-trig-bfin-timer.c33
-rw-r--r--drivers/staging/iio/trigger/iio-trig-periodic-rtc.c29
32 files changed, 547 insertions, 885 deletions
diff --git a/drivers/staging/iio/Documentation/generic_buffer.c b/drivers/staging/iio/Documentation/generic_buffer.c
index 40d0ecac047f..044ea196aa6f 100644
--- a/drivers/staging/iio/Documentation/generic_buffer.c
+++ b/drivers/staging/iio/Documentation/generic_buffer.c
@@ -305,9 +305,12 @@ int main(int argc, char **argv)
read_size = read(fp,
data,
toread*scan_size);
- if (read_size == -EAGAIN) {
- printf("nothing available\n");
- continue;
+ if (read_size < 0) {
+ if (errno == -EAGAIN) {
+ printf("nothing available\n");
+ continue;
+ } else
+ break;
}
for (i = 0; i < read_size/scan_size; i++)
process_scan(data + scan_size*i,
diff --git a/drivers/staging/iio/Documentation/iio_event_monitor.c b/drivers/staging/iio/Documentation/iio_event_monitor.c
index 3a9b00087403..569d6f8face5 100644
--- a/drivers/staging/iio/Documentation/iio_event_monitor.c
+++ b/drivers/staging/iio/Documentation/iio_event_monitor.c
@@ -46,6 +46,9 @@ static const char * const iio_chan_type_name_spec[] = {
[IIO_TIMESTAMP] = "timestamp",
[IIO_CAPACITANCE] = "capacitance",
[IIO_ALTVOLTAGE] = "altvoltage",
+ [IIO_CCT] = "cct",
+ [IIO_PRESSURE] = "pressure",
+ [IIO_HUMIDITYRELATIVE] = "humidityrelative",
};
static const char * const iio_ev_type_text[] = {
@@ -70,6 +73,8 @@ static const char * const iio_modifier_names[] = {
[IIO_MOD_LIGHT_IR] = "ir",
[IIO_MOD_ROOT_SUM_SQUARED_X_Y] = "sqrt(x^2+y^2)",
[IIO_MOD_SUM_SQUARED_X_Y_Z] = "x^2+y^2+z^2",
+ [IIO_MOD_LIGHT_BOTH] = "both",
+ [IIO_MOD_LIGHT_IR] = "ir",
[IIO_MOD_LIGHT_CLEAR] = "clear",
[IIO_MOD_LIGHT_RED] = "red",
[IIO_MOD_LIGHT_GREEN] = "green",
@@ -100,6 +105,9 @@ static bool event_is_known(struct iio_event_data *event)
case IIO_TIMESTAMP:
case IIO_CAPACITANCE:
case IIO_ALTVOLTAGE:
+ case IIO_CCT:
+ case IIO_PRESSURE:
+ case IIO_HUMIDITYRELATIVE:
break;
default:
return false;
diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h
index a9cfc06edb01..0973a092224a 100644
--- a/drivers/staging/iio/Documentation/iio_utils.h
+++ b/drivers/staging/iio/Documentation/iio_utils.h
@@ -633,7 +633,7 @@ error_free:
int read_sysfs_float(char *filename, char *basedir, float *val)
{
- float ret = 0;
+ int ret = 0;
FILE *sysfsfp;
char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
if (temp == NULL) {
@@ -653,9 +653,9 @@ error_free:
return ret;
}
-read_sysfs_string(const char *filename, const char *basedir, char *str)
+int read_sysfs_string(const char *filename, const char *basedir, char *str)
{
- float ret = 0;
+ int ret = 0;
FILE *sysfsfp;
char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
if (temp == NULL) {
diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio-trigger-sysfs b/drivers/staging/iio/Documentation/sysfs-bus-iio-trigger-sysfs
deleted file mode 100644
index 5235e6c749ab..000000000000
--- a/drivers/staging/iio/Documentation/sysfs-bus-iio-trigger-sysfs
+++ /dev/null
@@ -1,11 +0,0 @@
-What: /sys/bus/iio/devices/triggerX/trigger_now
-KernelVersion: 2.6.38
-Contact: linux-iio@vger.kernel.org
-Description:
- This file is provided by the iio-trig-sysfs stand-alone trigger
- driver. Writing this file with any value triggers an event
- driven driver, associated with this trigger, to capture data
- into an in kernel buffer. This approach can be valuable during
- automated testing or in situations, where other trigger methods
- are not applicable. For example no RTC or spare GPIOs.
- X is the IIO index of the trigger.
diff --git a/drivers/staging/iio/Documentation/trigger.txt b/drivers/staging/iio/Documentation/trigger.txt
index 64e2e08fb4d0..7c0e505e4f04 100644
--- a/drivers/staging/iio/Documentation/trigger.txt
+++ b/drivers/staging/iio/Documentation/trigger.txt
@@ -31,5 +31,5 @@ consumers.
Trigger Consumers
Currently triggers are only used for the filling of software
-buffers and as such any device supporting INDIO_RING_TRIGGERED has the
+buffers and as such any device supporting INDIO_BUFFER_TRIGGERED has the
consumer interface automatically created.
diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig
index b36feb080cba..fa38be0982f9 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"
- select 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/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c
index 2105576fa77c..50ba1fa7f98a 100644
--- a/drivers/staging/iio/accel/adis16201_core.c
+++ b/drivers/staging/iio/accel/adis16201_core.c
@@ -131,17 +131,17 @@ static int adis16201_write_raw(struct iio_dev *indio_dev,
}
static const struct iio_chan_spec adis16201_channels[] = {
- ADIS_SUPPLY_CHAN(ADIS16201_SUPPLY_OUT, ADIS16201_SCAN_SUPPLY, 12),
- ADIS_TEMP_CHAN(ADIS16201_TEMP_OUT, ADIS16201_SCAN_TEMP, 12),
+ ADIS_SUPPLY_CHAN(ADIS16201_SUPPLY_OUT, ADIS16201_SCAN_SUPPLY, 0, 12),
+ ADIS_TEMP_CHAN(ADIS16201_TEMP_OUT, ADIS16201_SCAN_TEMP, 0, 12),
ADIS_ACCEL_CHAN(X, ADIS16201_XACCL_OUT, ADIS16201_SCAN_ACC_X,
- BIT(IIO_CHAN_INFO_CALIBBIAS), 14),
+ BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
ADIS_ACCEL_CHAN(Y, ADIS16201_YACCL_OUT, ADIS16201_SCAN_ACC_Y,
- BIT(IIO_CHAN_INFO_CALIBBIAS), 14),
- ADIS_AUX_ADC_CHAN(ADIS16201_AUX_ADC, ADIS16201_SCAN_AUX_ADC, 12),
+ BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
+ ADIS_AUX_ADC_CHAN(ADIS16201_AUX_ADC, ADIS16201_SCAN_AUX_ADC, 0, 12),
ADIS_INCLI_CHAN(X, ADIS16201_XINCL_OUT, ADIS16201_SCAN_INCLI_X,
- BIT(IIO_CHAN_INFO_CALIBBIAS), 14),
+ BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
ADIS_INCLI_CHAN(X, ADIS16201_YINCL_OUT, ADIS16201_SCAN_INCLI_Y,
- BIT(IIO_CHAN_INFO_CALIBBIAS), 14),
+ BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
IIO_CHAN_SOFT_TIMESTAMP(7)
};
diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c
index 409a28ed9043..f472137b0069 100644
--- a/drivers/staging/iio/accel/adis16203_core.c
+++ b/drivers/staging/iio/accel/adis16203_core.c
@@ -99,13 +99,14 @@ static int adis16203_read_raw(struct iio_dev *indio_dev,
}
static const struct iio_chan_spec adis16203_channels[] = {
- ADIS_SUPPLY_CHAN(ADIS16203_SUPPLY_OUT, ADIS16203_SCAN_SUPPLY, 12),
- ADIS_AUX_ADC_CHAN(ADIS16203_AUX_ADC, ADIS16203_SCAN_AUX_ADC, 12),
+ ADIS_SUPPLY_CHAN(ADIS16203_SUPPLY_OUT, ADIS16203_SCAN_SUPPLY, 0, 12),
+ ADIS_AUX_ADC_CHAN(ADIS16203_AUX_ADC, ADIS16203_SCAN_AUX_ADC, 0, 12),
ADIS_INCLI_CHAN(X, ADIS16203_XINCL_OUT, ADIS16203_SCAN_INCLI_X,
- BIT(IIO_CHAN_INFO_CALIBBIAS), 14),
+ BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
/* Fixme: Not what it appears to be - see data sheet */
- ADIS_INCLI_CHAN(Y, ADIS16203_YINCL_OUT, ADIS16203_SCAN_INCLI_Y, 0, 14),
- ADIS_TEMP_CHAN(ADIS16203_TEMP_OUT, ADIS16203_SCAN_TEMP, 12),
+ ADIS_INCLI_CHAN(Y, ADIS16203_YINCL_OUT, ADIS16203_SCAN_INCLI_Y,
+ 0, 0, 14),
+ ADIS_TEMP_CHAN(ADIS16203_TEMP_OUT, ADIS16203_SCAN_TEMP, 0, 12),
IIO_CHAN_SOFT_TIMESTAMP(5),
};
diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c
index b8ea76857cd6..19eaebc77d7a 100644
--- a/drivers/staging/iio/accel/adis16204_core.c
+++ b/drivers/staging/iio/accel/adis16204_core.c
@@ -136,15 +136,15 @@ static int adis16204_write_raw(struct iio_dev *indio_dev,
}
static const struct iio_chan_spec adis16204_channels[] = {
- ADIS_SUPPLY_CHAN(ADIS16204_SUPPLY_OUT, ADIS16204_SCAN_SUPPLY, 12),
- ADIS_AUX_ADC_CHAN(ADIS16204_AUX_ADC, ADIS16204_SCAN_AUX_ADC, 12),
- ADIS_TEMP_CHAN(ADIS16204_TEMP_OUT, ADIS16204_SCAN_TEMP, 12),
+ ADIS_SUPPLY_CHAN(ADIS16204_SUPPLY_OUT, ADIS16204_SCAN_SUPPLY, 0, 12),
+ ADIS_AUX_ADC_CHAN(ADIS16204_AUX_ADC, ADIS16204_SCAN_AUX_ADC, 0, 12),
+ ADIS_TEMP_CHAN(ADIS16204_TEMP_OUT, ADIS16204_SCAN_TEMP, 0, 12),
ADIS_ACCEL_CHAN(X, ADIS16204_XACCL_OUT, ADIS16204_SCAN_ACC_X,
- BIT(IIO_CHAN_INFO_CALIBBIAS) | BIT(IIO_CHAN_INFO_PEAK), 14),
+ BIT(IIO_CHAN_INFO_CALIBBIAS) | BIT(IIO_CHAN_INFO_PEAK), 0, 14),
ADIS_ACCEL_CHAN(Y, ADIS16204_YACCL_OUT, ADIS16204_SCAN_ACC_Y,
- BIT(IIO_CHAN_INFO_CALIBBIAS) | BIT(IIO_CHAN_INFO_PEAK), 14),
+ BIT(IIO_CHAN_INFO_CALIBBIAS) | BIT(IIO_CHAN_INFO_PEAK), 0, 14),
ADIS_ACCEL_CHAN(ROOT_SUM_SQUARED_X_Y, ADIS16204_XY_RSS_OUT,
- ADIS16204_SCAN_ACC_XY, BIT(IIO_CHAN_INFO_PEAK), 14),
+ ADIS16204_SCAN_ACC_XY, BIT(IIO_CHAN_INFO_PEAK), 0, 14),
IIO_CHAN_SOFT_TIMESTAMP(5),
};
diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c
index 4492e51d8886..374dc6edbcf5 100644
--- a/drivers/staging/iio/accel/adis16209_core.c
+++ b/drivers/staging/iio/accel/adis16209_core.c
@@ -130,16 +130,18 @@ static int adis16209_read_raw(struct iio_dev *indio_dev,
}
static const struct iio_chan_spec adis16209_channels[] = {
- ADIS_SUPPLY_CHAN(ADIS16209_SUPPLY_OUT, ADIS16209_SCAN_SUPPLY, 14),
- ADIS_TEMP_CHAN(ADIS16209_TEMP_OUT, ADIS16209_SCAN_TEMP, 12),
+ ADIS_SUPPLY_CHAN(ADIS16209_SUPPLY_OUT, ADIS16209_SCAN_SUPPLY, 0, 14),
+ ADIS_TEMP_CHAN(ADIS16209_TEMP_OUT, ADIS16209_SCAN_TEMP, 0, 12),
ADIS_ACCEL_CHAN(X, ADIS16209_XACCL_OUT, ADIS16209_SCAN_ACC_X,
- BIT(IIO_CHAN_INFO_CALIBBIAS), 14),
+ BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
ADIS_ACCEL_CHAN(Y, ADIS16209_YACCL_OUT, ADIS16209_SCAN_ACC_Y,
- BIT(IIO_CHAN_INFO_CALIBBIAS), 14),
- ADIS_AUX_ADC_CHAN(ADIS16209_AUX_ADC, ADIS16209_SCAN_AUX_ADC, 12),
- ADIS_INCLI_CHAN(X, ADIS16209_XINCL_OUT, ADIS16209_SCAN_INCLI_X, 0, 14),
- ADIS_INCLI_CHAN(Y, ADIS16209_YINCL_OUT, ADIS16209_SCAN_INCLI_Y, 0, 14),
- ADIS_ROT_CHAN(X, ADIS16209_ROT_OUT, ADIS16209_SCAN_ROT, 0, 14),
+ BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
+ ADIS_AUX_ADC_CHAN(ADIS16209_AUX_ADC, ADIS16209_SCAN_AUX_ADC, 0, 12),
+ ADIS_INCLI_CHAN(X, ADIS16209_XINCL_OUT, ADIS16209_SCAN_INCLI_X,
+ 0, 0, 14),
+ ADIS_INCLI_CHAN(Y, ADIS16209_YINCL_OUT, ADIS16209_SCAN_INCLI_Y,
+ 0, 0, 14),
+ ADIS_ROT_CHAN(X, ADIS16209_ROT_OUT, ADIS16209_SCAN_ROT, 0, 0, 14),
IIO_CHAN_SOFT_TIMESTAMP(8)
};
diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c
index 3a303a03d028..74ace2a8769d 100644
--- a/drivers/staging/iio/accel/adis16240_core.c
+++ b/drivers/staging/iio/accel/adis16240_core.c
@@ -173,15 +173,15 @@ static int adis16240_write_raw(struct iio_dev *indio_dev,
}
static const struct iio_chan_spec adis16240_channels[] = {
- ADIS_SUPPLY_CHAN(ADIS16240_SUPPLY_OUT, ADIS16240_SCAN_SUPPLY, 10),
- ADIS_AUX_ADC_CHAN(ADIS16240_AUX_ADC, ADIS16240_SCAN_AUX_ADC, 10),
+ ADIS_SUPPLY_CHAN(ADIS16240_SUPPLY_OUT, ADIS16240_SCAN_SUPPLY, 0, 10),
+ ADIS_AUX_ADC_CHAN(ADIS16240_AUX_ADC, ADIS16240_SCAN_AUX_ADC, 0, 10),
ADIS_ACCEL_CHAN(X, ADIS16240_XACCL_OUT, ADIS16240_SCAN_ACC_X,
- BIT(IIO_CHAN_INFO_CALIBBIAS) | BIT(IIO_CHAN_INFO_PEAK), 10),
+ BIT(IIO_CHAN_INFO_CALIBBIAS) | BIT(IIO_CHAN_INFO_PEAK), 0, 10),
ADIS_ACCEL_CHAN(Y, ADIS16240_YACCL_OUT, ADIS16240_SCAN_ACC_Y,
- BIT(IIO_CHAN_INFO_CALIBBIAS) | BIT(IIO_CHAN_INFO_PEAK), 10),
+ BIT(IIO_CHAN_INFO_CALIBBIAS) | BIT(IIO_CHAN_INFO_PEAK), 0, 10),
ADIS_ACCEL_CHAN(Z, ADIS16240_ZACCL_OUT, ADIS16240_SCAN_ACC_Z,
- BIT(IIO_CHAN_INFO_CALIBBIAS) | BIT(IIO_CHAN_INFO_PEAK), 10),
- ADIS_TEMP_CHAN(ADIS16240_TEMP_OUT, ADIS16240_SCAN_TEMP, 10),
+ BIT(IIO_CHAN_INFO_CALIBBIAS) | BIT(IIO_CHAN_INFO_PEAK), 0, 10),
+ ADIS_TEMP_CHAN(ADIS16240_TEMP_OUT, ADIS16240_SCAN_TEMP, 0, 10),
IIO_CHAN_SOFT_TIMESTAMP(6)
};
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index 79cefe0a516a..bf33fdead479 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -31,7 +31,7 @@ irqreturn_t lis3l02dq_data_rdy_trig_poll(int irq, void *private)
struct lis3l02dq_state *st = iio_priv(indio_dev);
if (st->trigger_on) {
- iio_trigger_poll(st->trig, iio_get_time_ns());
+ iio_trigger_poll(st->trig);
return IRQ_HANDLED;
} else
return IRQ_WAKE_THREAD;
diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c
index 198710651e0e..33f0e9235be7 100644
--- a/drivers/staging/iio/accel/sca3000_ring.c
+++ b/drivers/staging/iio/accel/sca3000_ring.c
@@ -141,6 +141,11 @@ static int sca3000_ring_get_bytes_per_datum(struct iio_buffer *r)
return 6;
}
+static bool sca3000_ring_buf_data_available(struct iio_buffer *r)
+{
+ return r->stufftoread;
+}
+
static IIO_BUFFER_ENABLE_ATTR;
static IIO_BUFFER_LENGTH_ATTR;
@@ -274,6 +279,7 @@ 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,
+ .data_available = sca3000_ring_buf_data_available,
.release = sca3000_ring_release,
};
diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig
index b87e382ad768..d01c7076a342 100644
--- a/drivers/staging/iio/adc/Kconfig
+++ b/drivers/staging/iio/adc/Kconfig
@@ -3,13 +3,6 @@
#
menu "Analog to digital converters"
-config AD7291
- tristate "Analog Devices AD7291 ADC driver"
- depends on I2C
- help
- Say yes here to build support for Analog Devices AD7291
- 8 Channel ADC with temperature sensor.
-
config AD7606
tristate "Analog Devices AD7606 ADC driver"
depends on GPIOLIB
@@ -94,7 +87,7 @@ config LPC32XX_ADC
config MXS_LRADC
tristate "Freescale i.MX23/i.MX28 LRADC"
- depends on ARCH_MXS || COMPILE_TEST
+ depends on (ARCH_MXS || COMPILE_TEST) && HAS_IOMEM
depends on INPUT
select STMP_DEVICE
select IIO_BUFFER
diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile
index afdcd1ff08ff..1c4277dbd318 100644
--- a/drivers/staging/iio/adc/Makefile
+++ b/drivers/staging/iio/adc/Makefile
@@ -8,7 +8,6 @@ ad7606-$(CONFIG_AD7606_IFACE_PARALLEL) += ad7606_par.o
ad7606-$(CONFIG_AD7606_IFACE_SPI) += ad7606_spi.o
obj-$(CONFIG_AD7606) += ad7606.o
-obj-$(CONFIG_AD7291) += ad7291.o
obj-$(CONFIG_AD7780) += ad7780.o
obj-$(CONFIG_AD7816) += ad7816.o
obj-$(CONFIG_AD7192) += ad7192.o
diff --git a/drivers/staging/iio/adc/ad7291.c b/drivers/staging/iio/adc/ad7291.c
deleted file mode 100644
index 357cef2a6f4c..000000000000
--- a/drivers/staging/iio/adc/ad7291.c
+++ /dev/null
@@ -1,580 +0,0 @@
-/*
- * AD7291 8-Channel, I2C, 12-Bit SAR ADC with Temperature Sensor
- *
- * Copyright 2010-2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/i2c.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/regulator/consumer.h>
-#include <linux/err.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-#include <linux/iio/events.h>
-
-#include "ad7291.h"
-
-/*
- * Simplified handling
- *
- * If no events enabled - single polled channel read
- * If event enabled direct reads disable unless channel
- * is in the read mask.
- *
- * The noise-delayed bit as per datasheet suggestion is always enabled.
- *
- */
-
-/*
- * AD7291 registers definition
- */
-#define AD7291_COMMAND 0x00
-#define AD7291_VOLTAGE 0x01
-#define AD7291_T_SENSE 0x02
-#define AD7291_T_AVERAGE 0x03
-#define AD7291_DATA_HIGH(x) ((x) * 3 + 0x4)
-#define AD7291_DATA_LOW(x) ((x) * 3 + 0x5)
-#define AD7291_HYST(x) ((x) * 3 + 0x6)
-#define AD7291_VOLTAGE_ALERT_STATUS 0x1F
-#define AD7291_T_ALERT_STATUS 0x20
-
-#define AD7291_VOLTAGE_LIMIT_COUNT 8
-
-
-/*
- * AD7291 command
- */
-#define AD7291_AUTOCYCLE (1 << 0)
-#define AD7291_RESET (1 << 1)
-#define AD7291_ALERT_CLEAR (1 << 2)
-#define AD7291_ALERT_POLARITY (1 << 3)
-#define AD7291_EXT_REF (1 << 4)
-#define AD7291_NOISE_DELAY (1 << 5)
-#define AD7291_T_SENSE_MASK (1 << 7)
-#define AD7291_VOLTAGE_MASK 0xFF00
-#define AD7291_VOLTAGE_OFFSET 0x8
-
-/*
- * AD7291 value masks
- */
-#define AD7291_CHANNEL_MASK 0xF000
-#define AD7291_BITS 12
-#define AD7291_VALUE_MASK 0xFFF
-#define AD7291_T_VALUE_SIGN 0x400
-#define AD7291_T_VALUE_FLOAT_OFFSET 2
-#define AD7291_T_VALUE_FLOAT_MASK 0x2
-
-#define AD7291_BITS 12
-
-struct ad7291_chip_info {
- struct i2c_client *client;
- struct regulator *reg;
- u16 command;
- u16 c_mask; /* Active voltage channels for events */
- struct mutex state_lock;
-};
-
-static int ad7291_i2c_read(struct ad7291_chip_info *chip, u8 reg, u16 *data)
-{
- struct i2c_client *client = chip->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 = ret;
-
- return 0;
-}
-
-static int ad7291_i2c_write(struct ad7291_chip_info *chip, u8 reg, u16 data)
-{
- return i2c_smbus_write_word_swapped(chip->client, reg, data);
-}
-
-static irqreturn_t ad7291_event_handler(int irq, void *private)
-{
- struct iio_dev *indio_dev = private;
- struct ad7291_chip_info *chip = iio_priv(private);
- u16 t_status, v_status;
- u16 command;
- int i;
- s64 timestamp = iio_get_time_ns();
-
- if (ad7291_i2c_read(chip, AD7291_T_ALERT_STATUS, &t_status))
- return IRQ_HANDLED;
-
- if (ad7291_i2c_read(chip, AD7291_VOLTAGE_ALERT_STATUS, &v_status))
- return IRQ_HANDLED;
-
- if (!(t_status || v_status))
- return IRQ_HANDLED;
-
- command = chip->command | AD7291_ALERT_CLEAR;
- ad7291_i2c_write(chip, AD7291_COMMAND, command);
-
- command = chip->command & ~AD7291_ALERT_CLEAR;
- ad7291_i2c_write(chip, AD7291_COMMAND, command);
-
- /* For now treat t_sense and t_sense_average the same */
- if ((t_status & (1 << 0)) || (t_status & (1 << 2)))
- iio_push_event(indio_dev,
- IIO_UNMOD_EVENT_CODE(IIO_TEMP,
- 0,
- IIO_EV_TYPE_THRESH,
- IIO_EV_DIR_FALLING),
- timestamp);
- if ((t_status & (1 << 1)) || (t_status & (1 << 3)))
- iio_push_event(indio_dev,
- IIO_UNMOD_EVENT_CODE(IIO_TEMP,
- 0,
- IIO_EV_TYPE_THRESH,
- IIO_EV_DIR_RISING),
- timestamp);
-
- for (i = 0; i < AD7291_VOLTAGE_LIMIT_COUNT*2; i += 2) {
- if (v_status & (1 << i))
- iio_push_event(indio_dev,
- IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE,
- i/2,
- IIO_EV_TYPE_THRESH,
- IIO_EV_DIR_FALLING),
- timestamp);
- if (v_status & (1 << (i + 1)))
- iio_push_event(indio_dev,
- IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE,
- i/2,
- IIO_EV_TYPE_THRESH,
- IIO_EV_DIR_RISING),
- timestamp);
- }
-
- return IRQ_HANDLED;
-}
-
-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 (chan->type) {
- case IIO_VOLTAGE:
- offset = chan->channel;
- break;
- case IIO_TEMP:
- offset = 8;
- break;
- default:
- return 0;
- }
-
- 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,
- 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(chan, dir, info),
- &uval);
- if (ret < 0)
- return ret;
-
- if (info == IIO_EV_INFO_HYSTERESIS || chan->type == IIO_VOLTAGE)
- *val = uval & AD7291_VALUE_MASK;
-
- else
- *val = sign_extend32(uval, 11);
-
- return IIO_VAL_INT;
-}
-
-static int ad7291_write_event_value(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
- enum iio_event_info info,
- int val, int val2)
-{
- struct ad7291_chip_info *chip = iio_priv(indio_dev);
-
- if (info == IIO_EV_INFO_HYSTERESIS || chan->type == IIO_VOLTAGE) {
- if (val > AD7291_VALUE_MASK || val < 0)
- return -EINVAL;
- } else {
- if (val > 2047 || val < -2048)
- return -EINVAL;
- }
-
- return ad7291_i2c_write(chip, ad7291_threshold_reg(chan, dir, info),
- val);
-}
-
-static int ad7291_read_event_config(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir)
-{
- struct 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 (chan->type) {
- case IIO_VOLTAGE:
- if (chip->c_mask & (1 << (15 - chan->channel)))
- return 1;
- else
- return 0;
- case IIO_TEMP:
- /* always on */
- return 1;
- default:
- return -EINVAL;
- }
-
-}
-
-static int ad7291_write_event_config(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
- int state)
-{
- int ret = 0;
- struct ad7291_chip_info *chip = iio_priv(indio_dev);
- unsigned int mask;
- u16 regval;
-
- mutex_lock(&chip->state_lock);
- regval = chip->command;
- /*
- * To be enabled the channel must simply be on. If any are enabled
- * use continuous sampling mode.
- * Possible to disable temp as well but that makes single read tricky.
- */
-
- mask = BIT(15 - chan->channel);
-
- switch (chan->type) {
- case IIO_VOLTAGE:
- if ((!state) && (chip->c_mask & mask))
- chip->c_mask &= ~mask;
- else if (state && (!(chip->c_mask & mask)))
- chip->c_mask |= mask;
- else
- break;
-
- regval &= ~AD7291_AUTOCYCLE;
- regval |= chip->c_mask;
- if (chip->c_mask) /* Enable autocycle? */
- regval |= AD7291_AUTOCYCLE;
-
- ret = ad7291_i2c_write(chip, AD7291_COMMAND, regval);
- if (ret < 0)
- goto error_ret;
-
- chip->command = regval;
- break;
- default:
- ret = -EINVAL;
- }
-
-error_ret:
- mutex_unlock(&chip->state_lock);
- return ret;
-}
-
-static int ad7291_read_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int *val,
- int *val2,
- long mask)
-{
- int ret;
- struct ad7291_chip_info *chip = iio_priv(indio_dev);
- u16 regval;
-
- switch (mask) {
- case IIO_CHAN_INFO_RAW:
- switch (chan->type) {
- case IIO_VOLTAGE:
- mutex_lock(&chip->state_lock);
- /* If in autocycle mode drop through */
- if (chip->command & AD7291_AUTOCYCLE) {
- mutex_unlock(&chip->state_lock);
- return -EBUSY;
- }
- /* Enable this channel alone */
- regval = chip->command & (~AD7291_VOLTAGE_MASK);
- regval |= 1 << (15 - chan->channel);
- ret = ad7291_i2c_write(chip, AD7291_COMMAND, regval);
- if (ret < 0) {
- mutex_unlock(&chip->state_lock);
- return ret;
- }
- /* Read voltage */
- ret = i2c_smbus_read_word_swapped(chip->client,
- AD7291_VOLTAGE);
- if (ret < 0) {
- mutex_unlock(&chip->state_lock);
- return ret;
- }
- *val = ret & AD7291_VALUE_MASK;
- mutex_unlock(&chip->state_lock);
- return IIO_VAL_INT;
- case IIO_TEMP:
- /* Assumes tsense bit of command register always set */
- ret = i2c_smbus_read_word_swapped(chip->client,
- AD7291_T_SENSE);
- if (ret < 0)
- return ret;
- *val = sign_extend32(ret, 11);
- return IIO_VAL_INT;
- default:
- return -EINVAL;
- }
- case IIO_CHAN_INFO_AVERAGE_RAW:
- ret = i2c_smbus_read_word_swapped(chip->client,
- AD7291_T_AVERAGE);
- if (ret < 0)
- return ret;
- *val = sign_extend32(ret, 11);
- return IIO_VAL_INT;
- case IIO_CHAN_INFO_SCALE:
- switch (chan->type) {
- case IIO_VOLTAGE:
- if (chip->reg) {
- int vref;
- vref = regulator_get_voltage(chip->reg);
- if (vref < 0)
- return vref;
- *val = vref / 1000;
- } else {
- *val = 2500;
- }
- *val2 = AD7291_BITS;
- return IIO_VAL_FRACTIONAL_LOG2;
- case IIO_TEMP:
- /*
- * One LSB of the ADC corresponds to 0.25 deg C.
- * The temperature reading is in 12-bit twos
- * complement format
- */
- *val = 250;
- return IIO_VAL_INT;
- default:
- return -EINVAL;
- }
- default:
- return -EINVAL;
- }
-}
-
-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, \
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
- .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
- .indexed = 1, \
- .channel = _chan, \
- .event_spec = ad7291_events, \
- .num_event_specs = ARRAY_SIZE(ad7291_events), \
-}
-
-static const struct iio_chan_spec ad7291_channels[] = {
- AD7291_VOLTAGE_CHAN(0),
- AD7291_VOLTAGE_CHAN(1),
- AD7291_VOLTAGE_CHAN(2),
- AD7291_VOLTAGE_CHAN(3),
- AD7291_VOLTAGE_CHAN(4),
- AD7291_VOLTAGE_CHAN(5),
- AD7291_VOLTAGE_CHAN(6),
- AD7291_VOLTAGE_CHAN(7),
- {
- .type = IIO_TEMP,
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
- BIT(IIO_CHAN_INFO_AVERAGE_RAW) |
- BIT(IIO_CHAN_INFO_SCALE),
- .indexed = 1,
- .channel = 0,
- .event_spec = ad7291_events,
- .num_event_specs = ARRAY_SIZE(ad7291_events),
- }
-};
-
-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,
- .driver_module = THIS_MODULE,
-};
-
-static int ad7291_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct ad7291_platform_data *pdata = client->dev.platform_data;
- struct ad7291_chip_info *chip;
- struct iio_dev *indio_dev;
- int ret = 0;
-
- 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 = devm_regulator_get(&client->dev, "vref");
- if (IS_ERR(chip->reg))
- return ret;
-
- ret = regulator_enable(chip->reg);
- if (ret)
- return ret;
- }
-
- mutex_init(&chip->state_lock);
- /* this is only used for device removal purposes */
- i2c_set_clientdata(client, indio_dev);
-
- chip->client = client;
-
- chip->command = AD7291_NOISE_DELAY |
- AD7291_T_SENSE_MASK | /* Tsense always enabled */
- AD7291_ALERT_POLARITY; /* set irq polarity low level */
-
- if (pdata && pdata->use_external_ref)
- chip->command |= AD7291_EXT_REF;
-
- indio_dev->name = id->name;
- indio_dev->channels = ad7291_channels;
- indio_dev->num_channels = ARRAY_SIZE(ad7291_channels);
-
- indio_dev->dev.parent = &client->dev;
- indio_dev->info = &ad7291_info;
- indio_dev->modes = INDIO_DIRECT_MODE;
-
- ret = ad7291_i2c_write(chip, AD7291_COMMAND, AD7291_RESET);
- if (ret) {
- ret = -EIO;
- goto error_disable_reg;
- }
-
- ret = ad7291_i2c_write(chip, AD7291_COMMAND, chip->command);
- if (ret) {
- ret = -EIO;
- goto error_disable_reg;
- }
-
- if (client->irq > 0) {
- ret = request_threaded_irq(client->irq,
- NULL,
- &ad7291_event_handler,
- IRQF_TRIGGER_LOW | IRQF_ONESHOT,
- id->name,
- indio_dev);
- if (ret)
- goto error_disable_reg;
- }
-
- ret = iio_device_register(indio_dev);
- if (ret)
- goto error_unreg_irq;
-
- return 0;
-
-error_unreg_irq:
- if (client->irq)
- free_irq(client->irq, indio_dev);
-error_disable_reg:
- if (chip->reg)
- regulator_disable(chip->reg);
-
- return ret;
-}
-
-static int ad7291_remove(struct i2c_client *client)
-{
- struct iio_dev *indio_dev = i2c_get_clientdata(client);
- struct ad7291_chip_info *chip = iio_priv(indio_dev);
-
- iio_device_unregister(indio_dev);
-
- if (client->irq)
- free_irq(client->irq, indio_dev);
-
- if (chip->reg)
- regulator_disable(chip->reg);
-
- return 0;
-}
-
-static const struct i2c_device_id ad7291_id[] = {
- { "ad7291", 0 },
- {}
-};
-
-MODULE_DEVICE_TABLE(i2c, ad7291_id);
-
-static struct i2c_driver ad7291_driver = {
- .driver = {
- .name = KBUILD_MODNAME,
- },
- .probe = ad7291_probe,
- .remove = ad7291_remove,
- .id_table = ad7291_id,
-};
-module_i2c_driver(ad7291_driver);
-
-MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
-MODULE_DESCRIPTION("Analog Devices AD7291 ADC driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/adc/ad7291.h b/drivers/staging/iio/adc/ad7291.h
deleted file mode 100644
index bbd89fa51188..000000000000
--- a/drivers/staging/iio/adc/ad7291.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef __IIO_AD7291_H__
-#define __IIO_AD7291_H__
-
-/**
- * struct ad7291_platform_data - AD7291 platform data
- * @use_external_ref: Whether to use an external or internal reference voltage
- */
-struct ad7291_platform_data {
- bool use_external_ref;
-};
-
-#endif
diff --git a/drivers/staging/iio/adc/ad7606_par.c b/drivers/staging/iio/adc/ad7606_par.c
index 8a48d18de788..7511839ba94e 100644
--- a/drivers/staging/iio/adc/ad7606_par.c
+++ b/drivers/staging/iio/adc/ad7606_par.c
@@ -53,7 +53,7 @@ static int ad7606_par_probe(struct platform_device *pdev)
struct iio_dev *indio_dev;
void __iomem *addr;
resource_size_t remap_size;
- int ret, irq;
+ int irq;
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
@@ -62,56 +62,31 @@ static int ad7606_par_probe(struct platform_device *pdev)
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res)
- return -ENODEV;
+ addr = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(addr))
+ return PTR_ERR(addr);
remap_size = resource_size(res);
- /* Request the regions */
- if (!request_mem_region(res->start, remap_size, "iio-ad7606")) {
- ret = -EBUSY;
- goto out1;
- }
- addr = ioremap(res->start, remap_size);
- if (!addr) {
- ret = -ENOMEM;
- goto out1;
- }
-
indio_dev = ad7606_probe(&pdev->dev, irq, addr,
platform_get_device_id(pdev)->driver_data,
remap_size > 1 ? &ad7606_par16_bops :
&ad7606_par8_bops);
- if (IS_ERR(indio_dev)) {
- ret = PTR_ERR(indio_dev);
- goto out2;
- }
+ if (IS_ERR(indio_dev))
+ return PTR_ERR(indio_dev);
platform_set_drvdata(pdev, indio_dev);
return 0;
-
-out2:
- iounmap(addr);
-out1:
- release_mem_region(res->start, remap_size);
-
- return ret;
}
static int ad7606_par_remove(struct platform_device *pdev)
{
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
- struct resource *res;
- struct ad7606_state *st = iio_priv(indio_dev);
ad7606_remove(indio_dev, platform_get_irq(pdev, 0));
- iounmap(st->base_address);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(res->start, resource_size(res));
-
return 0;
}
diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c
index dae8d1a9038e..468327f4a753 100644
--- a/drivers/staging/iio/adc/mxs-lradc.c
+++ b/drivers/staging/iio/adc/mxs-lradc.c
@@ -846,6 +846,14 @@ static int mxs_lradc_read_single(struct iio_dev *iio_dev, int chan, int *val)
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. */
mxs_lradc_reg_clear(lradc, LRADC_CTRL4_LRADCSELECT_MASK(0),
LRADC_CTRL4);
@@ -961,15 +969,11 @@ static int mxs_lradc_write_raw(struct iio_dev *iio_dev,
if (val == scale_avail[MXS_LRADC_DIV_DISABLED].integer &&
val2 == scale_avail[MXS_LRADC_DIV_DISABLED].nano) {
/* divider by two disabled */
- writel(1 << LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET,
- lradc->base + LRADC_CTRL2 + STMP_OFFSET_REG_CLR);
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 */
- writel(1 << LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET,
- lradc->base + LRADC_CTRL2 + STMP_OFFSET_REG_SET);
set_bit(chan->channel, &lradc->is_divided);
ret = 0;
}
@@ -1166,7 +1170,7 @@ static irqreturn_t mxs_lradc_handle_irq(int irq, void *data)
mxs_lradc_handle_touch(lradc);
if (iio_buffer_enabled(iio))
- iio_trigger_poll(iio->trig, iio_get_time_ns());
+ iio_trigger_poll(iio->trig);
else if (reg & LRADC_CTRL1_LRADC_IRQ(0))
complete(&lradc->completion);
diff --git a/drivers/staging/iio/frequency/ad9832.c b/drivers/staging/iio/frequency/ad9832.c
index c7d0307c8e76..cf68159a5848 100644
--- a/drivers/staging/iio/frequency/ad9832.c
+++ b/drivers/staging/iio/frequency/ad9832.c
@@ -57,7 +57,7 @@ static int ad9832_write_frequency(struct ad9832_state *st,
}
static int ad9832_write_phase(struct ad9832_state *st,
- unsigned long addr, unsigned long phase)
+ unsigned long addr, unsigned long phase)
{
if (phase > (1 << AD9832_PHASE_BITS))
return -EINVAL;
@@ -72,10 +72,8 @@ static int ad9832_write_phase(struct ad9832_state *st,
return spi_sync(st->spi, &st->phase_msg);
}
-static ssize_t ad9832_write(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
+static ssize_t ad9832_write(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ad9832_state *st = iio_priv(indio_dev);
@@ -109,11 +107,11 @@ static ssize_t ad9832_write(struct device *dev,
ret = spi_sync(st->spi, &st->msg);
break;
case AD9832_FREQ_SYM:
- if (val == 1)
+ if (val == 1) {
st->ctrl_fp |= AD9832_FREQ;
- else if (val == 0)
+ } else if (val == 0) {
st->ctrl_fp &= ~AD9832_FREQ;
- else {
+ } else {
ret = -EINVAL;
break;
}
@@ -122,7 +120,7 @@ static ssize_t ad9832_write(struct device *dev,
ret = spi_sync(st->spi, &st->msg);
break;
case AD9832_PHASE_SYM:
- if (val < 0 || val > 3) {
+ if (val > 3) {
ret = -EINVAL;
break;
}
diff --git a/drivers/staging/iio/frequency/ad9850.c b/drivers/staging/iio/frequency/ad9850.c
index af877ff680e9..8727933cafcf 100644
--- a/drivers/staging/iio/frequency/ad9850.c
+++ b/drivers/staging/iio/frequency/ad9850.c
@@ -21,9 +21,6 @@
#define DRV_NAME "ad9850"
-#define value_mask (u16)0xf000
-#define addr_shift 12
-
/* Register format: 4 bits addr + 12 bits value */
struct ad9850_config {
u8 control[5];
@@ -50,9 +47,6 @@ static ssize_t ad9850_set_parameter(struct device *dev,
mutex_lock(&st->lock);
ret = spi_sync_transfer(st->sdev, &xfer, 1);
- if (ret)
- goto error_ret;
-error_ret:
mutex_unlock(&st->lock);
return ret ? ret : len;
diff --git a/drivers/staging/iio/iio_simple_dummy.c b/drivers/staging/iio/iio_simple_dummy.c
index fd334a03a49a..bf78e6f0311f 100644
--- a/drivers/staging/iio/iio_simple_dummy.c
+++ b/drivers/staging/iio/iio_simple_dummy.c
@@ -550,6 +550,7 @@ error_ret:
static __init int iio_dummy_init(void)
{
int i, ret;
+
if (instances > 10) {
instances = 1;
return -EINVAL;
@@ -577,6 +578,7 @@ module_init(iio_dummy_init);
static __exit void iio_dummy_exit(void)
{
int i;
+
for (i = 0; i < instances; i++)
iio_dummy_remove(i);
kfree(iio_dummy_devs);
diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x_core.c
index 9e0f2a9c73ae..ab338e3ddd05 100644
--- a/drivers/staging/iio/light/tsl2x7x_core.c
+++ b/drivers/staging/iio/light/tsl2x7x_core.c
@@ -667,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) {
diff --git a/drivers/staging/iio/magnetometer/Kconfig b/drivers/staging/iio/magnetometer/Kconfig
index 34634da1f9f7..dec814a7a073 100644
--- a/drivers/staging/iio/magnetometer/Kconfig
+++ b/drivers/staging/iio/magnetometer/Kconfig
@@ -4,15 +4,37 @@
menu "Magnetometer sensors"
config SENSORS_HMC5843
- tristate "Honeywell HMC5843/5883/5883L 3-Axis Magnetometer"
- depends on I2C
+ tristate
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
+
+config SENSORS_HMC5843_I2C
+ tristate "Honeywell HMC5843/5883/5883L 3-Axis Magnetometer (I2C)"
+ depends on I2C
+ select SENSORS_HMC5843
+ select REGMAP_I2C
help
Say Y here to add support for the Honeywell HMC5843, HMC5883 and
HMC5883L 3-Axis Magnetometer (digital compass).
- To compile this driver as a module, choose M here: the module
- will be called hmc5843.
+ This driver can also be compiled as a set of modules.
+ If so, these modules will be created:
+ - hmc5843_core (core functions)
+ - hmc5843_i2c (support for HMC5843, HMC5883, HMC5883L and HMC5983)
+
+config SENSORS_HMC5843_SPI
+ tristate "Honeywell HMC5983 3-Axis Magnetometer (SPI)"
+ depends on SPI_MASTER
+ select SENSORS_HMC5843
+ select REGMAP_SPI
+ help
+ Say Y here to add support for the Honeywell HMC5983 3-Axis Magnetometer
+ (digital compass).
+
+ This driver can also be compiled as a set of modules.
+ If so, these modules will be created:
+ - hmc5843_core (core functions)
+ - hmc5843_spi (support for HMC5983)
+
endmenu
diff --git a/drivers/staging/iio/magnetometer/Makefile b/drivers/staging/iio/magnetometer/Makefile
index f9bfb2e11d7d..33761a19a956 100644
--- a/drivers/staging/iio/magnetometer/Makefile
+++ b/drivers/staging/iio/magnetometer/Makefile
@@ -2,4 +2,6 @@
# Makefile for industrial I/O Magnetometer sensors
#
-obj-$(CONFIG_SENSORS_HMC5843) += hmc5843.o
+obj-$(CONFIG_SENSORS_HMC5843) += hmc5843_core.o
+obj-$(CONFIG_SENSORS_HMC5843_I2C) += hmc5843_i2c.o
+obj-$(CONFIG_SENSORS_HMC5843_SPI) += hmc5843_spi.o
diff --git a/drivers/staging/iio/magnetometer/hmc5843.h b/drivers/staging/iio/magnetometer/hmc5843.h
new file mode 100644
index 000000000000..b784e3eb4591
--- /dev/null
+++ b/drivers/staging/iio/magnetometer/hmc5843.h
@@ -0,0 +1,59 @@
+/*
+ * Header file for hmc5843 driver
+ *
+ * Split from hmc5843.c
+ * Copyright (C) Josef Gajdusek <atx@atx.name>
+ *
+ * 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.
+ *
+ * */
+
+
+#ifndef HMC5843_CORE_H
+#define HMC5843_CORE_H
+
+#include <linux/regmap.h>
+#include <linux/iio/iio.h>
+
+#define HMC5843_CONFIG_REG_A 0x00
+#define HMC5843_CONFIG_REG_B 0x01
+#define HMC5843_MODE_REG 0x02
+#define HMC5843_DATA_OUT_MSB_REGS 0x03
+#define HMC5843_STATUS_REG 0x09
+#define HMC5843_ID_REG 0x0a
+#define HMC5843_ID_END 0x0c
+
+enum hmc5843_ids {
+ HMC5843_ID,
+ HMC5883_ID,
+ HMC5883L_ID,
+ HMC5983_ID,
+};
+
+struct hmc5843_data {
+ struct device *dev;
+ struct mutex lock;
+ struct regmap *regmap;
+ const struct hmc5843_chip_info *variant;
+ __be16 buffer[8]; /* 3x 16-bit channels + padding + 64-bit timestamp */
+};
+
+int hmc5843_common_probe(struct device *dev, struct regmap *regmap,
+ enum hmc5843_ids id);
+int hmc5843_common_remove(struct device *dev);
+
+int hmc5843_common_suspend(struct device *dev);
+int hmc5843_common_resume(struct device *dev);
+
+#ifdef CONFIG_PM_SLEEP
+static SIMPLE_DEV_PM_OPS(hmc5843_pm_ops,
+ hmc5843_common_suspend,
+ hmc5843_common_resume);
+#define HMC5843_PM_OPS (&hmc5843_pm_ops)
+#else
+#define HMC5843_PM_OPS NULL
+#endif
+
+#endif /* HMC5843_CORE_H */
diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843_core.c
index d4f4dd90c699..914ae1acd31d 100644
--- a/drivers/staging/iio/magnetometer/hmc5843.c
+++ b/drivers/staging/iio/magnetometer/hmc5843_core.c
@@ -4,6 +4,8 @@
Support for HMC5883 and HMC5883L by Peter Meerwald <pmeerw@pmeerw.net>.
+ Split to multiple files by Josef Gajdusek <atx@atx.name> - 2014
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
@@ -20,7 +22,7 @@
*/
#include <linux/module.h>
-#include <linux/i2c.h>
+#include <linux/regmap.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/trigger_consumer.h>
@@ -28,18 +30,7 @@
#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_MSB_REGS 0x03
-#define HMC5843_STATUS_REG 0x09
-#define HMC5843_ID_REG 0x0a
-
-enum hmc5843_ids {
- HMC5843_ID,
- HMC5883_ID,
- HMC5883L_ID,
-};
+#include "hmc5843.h"
/*
* Range gain settings in (+-)Ga
@@ -48,7 +39,7 @@ enum hmc5843_ids {
*/
#define HMC5843_RANGE_GAIN_OFFSET 0x05
#define HMC5843_RANGE_GAIN_DEFAULT 0x01
-#define HMC5843_RANGE_GAINS 8
+#define HMC5843_RANGE_GAIN_MASK 0xe0
/* Device status */
#define HMC5843_DATA_READY 0x01
@@ -67,7 +58,7 @@ enum hmc5843_ids {
*/
#define HMC5843_RATE_OFFSET 0x02
#define HMC5843_RATE_DEFAULT 0x04
-#define HMC5843_RATES 7
+#define HMC5843_RATE_MASK 0x1c
/* Device measurement configuration */
#define HMC5843_MEAS_CONF_NORMAL 0x00
@@ -76,15 +67,15 @@ enum hmc5843_ids {
#define HMC5843_MEAS_CONF_MASK 0x03
/* Scaling factors: 10000000/Gain */
-static const int hmc5843_regval_to_nanoscale[HMC5843_RANGE_GAINS] = {
+static const int hmc5843_regval_to_nanoscale[] = {
6173, 7692, 10309, 12821, 18868, 21739, 25641, 35714
};
-static const int hmc5883_regval_to_nanoscale[HMC5843_RANGE_GAINS] = {
+static const int hmc5883_regval_to_nanoscale[] = {
7812, 9766, 13021, 16287, 24096, 27701, 32573, 45662
};
-static const int hmc5883l_regval_to_nanoscale[HMC5843_RANGE_GAINS] = {
+static const int hmc5883l_regval_to_nanoscale[] = {
7299, 9174, 12195, 15152, 22727, 25641, 30303, 43478
};
@@ -101,32 +92,27 @@ static const int hmc5883l_regval_to_nanoscale[HMC5843_RANGE_GAINS] = {
* 6 | 50 | 75
* 7 | Not used | Not used
*/
-static const int hmc5843_regval_to_samp_freq[7][2] = {
+static const int hmc5843_regval_to_samp_freq[][2] = {
{0, 500000}, {1, 0}, {2, 0}, {5, 0}, {10, 0}, {20, 0}, {50, 0}
};
-static const int hmc5883_regval_to_samp_freq[7][2] = {
+static const int hmc5883_regval_to_samp_freq[][2] = {
{0, 750000}, {1, 500000}, {3, 0}, {7, 500000}, {15, 0}, {30, 0},
{75, 0}
};
+static const int hmc5983_regval_to_samp_freq[][2] = {
+ {0, 750000}, {1, 500000}, {3, 0}, {7, 500000}, {15, 0}, {30, 0},
+ {75, 0}, {220, 0}
+};
+
/* Describe chip variants */
struct hmc5843_chip_info {
const struct iio_chan_spec *channels;
const int (*regval_to_samp_freq)[2];
+ const int n_regval_to_samp_freq;
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 */
+ const int n_regval_to_nanoscale;
};
/* The lower two bits contain the current conversion mode */
@@ -135,10 +121,8 @@ static s32 hmc5843_set_mode(struct hmc5843_data *data, u8 operating_mode)
int ret;
mutex_lock(&data->lock);
- ret = i2c_smbus_write_byte_data(data->client, HMC5843_MODE_REG,
- operating_mode & HMC5843_MODE_MASK);
- if (ret >= 0)
- data->operating_mode = operating_mode;
+ ret = regmap_update_bits(data->regmap, HMC5843_MODE_REG,
+ HMC5843_MODE_MASK, operating_mode);
mutex_unlock(&data->lock);
return ret;
@@ -146,21 +130,21 @@ static s32 hmc5843_set_mode(struct hmc5843_data *data, u8 operating_mode)
static int hmc5843_wait_measurement(struct hmc5843_data *data)
{
- s32 result;
int tries = 150;
+ int val;
+ int ret;
while (tries-- > 0) {
- result = i2c_smbus_read_byte_data(data->client,
- HMC5843_STATUS_REG);
- if (result < 0)
- return result;
- if (result & HMC5843_DATA_READY)
+ ret = regmap_read(data->regmap, HMC5843_STATUS_REG, &val);
+ if (ret < 0)
+ return ret;
+ if (val & HMC5843_DATA_READY)
break;
msleep(20);
}
if (tries < 0) {
- dev_err(&data->client->dev, "data not ready\n");
+ dev_err(data->dev, "data not ready\n");
return -EIO;
}
@@ -171,20 +155,20 @@ static int hmc5843_wait_measurement(struct hmc5843_data *data)
static int hmc5843_read_measurement(struct hmc5843_data *data,
int idx, int *val)
{
- s32 result;
__be16 values[3];
+ int ret;
mutex_lock(&data->lock);
- result = hmc5843_wait_measurement(data);
- if (result < 0) {
+ ret = hmc5843_wait_measurement(data);
+ if (ret < 0) {
mutex_unlock(&data->lock);
- return result;
+ return ret;
}
- result = i2c_smbus_read_i2c_block_data(data->client,
- HMC5843_DATA_OUT_MSB_REGS, sizeof(values), (u8 *) values);
+ ret = regmap_bulk_read(data->regmap, HMC5843_DATA_OUT_MSB_REGS,
+ values, sizeof(values));
mutex_unlock(&data->lock);
- if (result < 0)
- return -EINVAL;
+ if (ret < 0)
+ return ret;
*val = sign_extend32(be16_to_cpu(values[idx]), 15);
return IIO_VAL_INT;
@@ -208,16 +192,13 @@ static int hmc5843_read_measurement(struct hmc5843_data *data,
* and BN.
*
*/
-static s32 hmc5843_set_meas_conf(struct hmc5843_data *data, u8 meas_conf)
+static int hmc5843_set_meas_conf(struct hmc5843_data *data, u8 meas_conf)
{
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;
+ ret = regmap_update_bits(data->regmap, HMC5843_CONFIG_REG_A,
+ HMC5843_MEAS_CONF_MASK, meas_conf);
mutex_unlock(&data->lock);
return ret;
@@ -228,7 +209,15 @@ static ssize_t hmc5843_show_measurement_configuration(struct device *dev,
char *buf)
{
struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
- return sprintf(buf, "%d\n", data->meas_conf);
+ int val;
+ int ret;
+
+ ret = regmap_read(data->regmap, HMC5843_CONFIG_REG_A, &val);
+ if (ret)
+ return ret;
+ val &= HMC5843_MEAS_CONF_MASK;
+
+ return sprintf(buf, "%d\n", val);
}
static ssize_t hmc5843_set_measurement_configuration(struct device *dev,
@@ -264,7 +253,7 @@ static ssize_t hmc5843_show_samp_freq_avail(struct device *dev,
size_t len = 0;
int i;
- for (i = 0; i < HMC5843_RATES; i++)
+ for (i = 0; i < data->variant->n_regval_to_samp_freq; 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]);
@@ -282,10 +271,8 @@ static int hmc5843_set_samp_freq(struct hmc5843_data *data, u8 rate)
int ret;
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;
+ ret = regmap_update_bits(data->regmap, HMC5843_CONFIG_REG_A,
+ HMC5843_RATE_MASK, rate << HMC5843_RATE_OFFSET);
mutex_unlock(&data->lock);
return ret;
@@ -296,7 +283,7 @@ static int hmc5843_get_samp_freq_index(struct hmc5843_data *data,
{
int i;
- for (i = 0; i < HMC5843_RATES; i++)
+ for (i = 0; i < data->variant->n_regval_to_samp_freq; i++)
if (val == data->variant->regval_to_samp_freq[i][0] &&
val2 == data->variant->regval_to_samp_freq[i][1])
return i;
@@ -309,10 +296,9 @@ static int hmc5843_set_range_gain(struct hmc5843_data *data, u8 range)
int ret;
mutex_lock(&data->lock);
- ret = i2c_smbus_write_byte_data(data->client, HMC5843_CONFIG_REG_B,
- range << HMC5843_RANGE_GAIN_OFFSET);
- if (ret >= 0)
- data->range = range;
+ ret = regmap_update_bits(data->regmap, HMC5843_CONFIG_REG_B,
+ HMC5843_RANGE_GAIN_MASK,
+ range << HMC5843_RANGE_GAIN_OFFSET);
mutex_unlock(&data->lock);
return ret;
@@ -326,7 +312,7 @@ static ssize_t hmc5843_show_scale_avail(struct device *dev,
size_t len = 0;
int i;
- for (i = 0; i < HMC5843_RANGE_GAINS; i++)
+ for (i = 0; i < data->variant->n_regval_to_nanoscale; i++)
len += scnprintf(buf + len, PAGE_SIZE - len,
"0.%09d ", data->variant->regval_to_nanoscale[i]);
@@ -346,7 +332,7 @@ static int hmc5843_get_scale_index(struct hmc5843_data *data, int val, int val2)
if (val != 0)
return -EINVAL;
- for (i = 0; i < HMC5843_RANGE_GAINS; i++)
+ for (i = 0; i < data->variant->n_regval_to_nanoscale; i++)
if (val2 == data->variant->regval_to_nanoscale[i])
return i;
@@ -358,17 +344,27 @@ static int hmc5843_read_raw(struct iio_dev *indio_dev,
int *val, int *val2, long mask)
{
struct hmc5843_data *data = iio_priv(indio_dev);
+ int rval;
+ int ret;
switch (mask) {
case IIO_CHAN_INFO_RAW:
return hmc5843_read_measurement(data, chan->scan_index, val);
case IIO_CHAN_INFO_SCALE:
+ ret = regmap_read(data->regmap, HMC5843_CONFIG_REG_B, &rval);
+ if (ret < 0)
+ return ret;
+ rval >>= HMC5843_RANGE_GAIN_OFFSET;
*val = 0;
- *val2 = data->variant->regval_to_nanoscale[data->range];
+ *val2 = data->variant->regval_to_nanoscale[rval];
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];
+ ret = regmap_read(data->regmap, HMC5843_CONFIG_REG_A, &rval);
+ if (ret < 0)
+ return ret;
+ rval >>= HMC5843_RATE_OFFSET;
+ *val = data->variant->regval_to_samp_freq[rval][0];
+ *val2 = data->variant->regval_to_samp_freq[rval][1];
return IIO_VAL_INT_PLUS_MICRO;
}
return -EINVAL;
@@ -426,9 +422,9 @@ static irqreturn_t hmc5843_trigger_handler(int irq, void *p)
goto done;
}
- ret = i2c_smbus_read_i2c_block_data(data->client,
- HMC5843_DATA_OUT_MSB_REGS, 3 * sizeof(__be16),
- (u8 *) data->buffer);
+ ret = regmap_bulk_read(data->regmap, HMC5843_DATA_OUT_MSB_REGS,
+ data->buffer, 3 * sizeof(__be16));
+
mutex_unlock(&data->lock);
if (ret < 0)
goto done;
@@ -466,7 +462,7 @@ static const struct iio_chan_spec hmc5843_channels[] = {
IIO_CHAN_SOFT_TIMESTAMP(3),
};
-/* Beware: Y and Z are exchanged on HMC5883 */
+/* Beware: Y and Z are exchanged on HMC5883 and 5983 */
static const struct iio_chan_spec hmc5883_channels[] = {
HMC5843_CHANNEL(X, 0),
HMC5843_CHANNEL(Z, 1),
@@ -489,18 +485,39 @@ static const struct hmc5843_chip_info hmc5843_chip_info_tbl[] = {
[HMC5843_ID] = {
.channels = hmc5843_channels,
.regval_to_samp_freq = hmc5843_regval_to_samp_freq,
+ .n_regval_to_samp_freq =
+ ARRAY_SIZE(hmc5843_regval_to_samp_freq),
.regval_to_nanoscale = hmc5843_regval_to_nanoscale,
+ .n_regval_to_nanoscale =
+ ARRAY_SIZE(hmc5843_regval_to_nanoscale),
},
[HMC5883_ID] = {
.channels = hmc5883_channels,
.regval_to_samp_freq = hmc5883_regval_to_samp_freq,
+ .n_regval_to_samp_freq =
+ ARRAY_SIZE(hmc5883_regval_to_samp_freq),
.regval_to_nanoscale = hmc5883_regval_to_nanoscale,
+ .n_regval_to_nanoscale =
+ ARRAY_SIZE(hmc5883_regval_to_nanoscale),
},
[HMC5883L_ID] = {
.channels = hmc5883_channels,
.regval_to_samp_freq = hmc5883_regval_to_samp_freq,
+ .n_regval_to_samp_freq =
+ ARRAY_SIZE(hmc5883_regval_to_samp_freq),
.regval_to_nanoscale = hmc5883l_regval_to_nanoscale,
+ .n_regval_to_nanoscale =
+ ARRAY_SIZE(hmc5883l_regval_to_nanoscale),
},
+ [HMC5983_ID] = {
+ .channels = hmc5883_channels,
+ .regval_to_samp_freq = hmc5983_regval_to_samp_freq,
+ .n_regval_to_samp_freq =
+ ARRAY_SIZE(hmc5983_regval_to_samp_freq),
+ .regval_to_nanoscale = hmc5883l_regval_to_nanoscale,
+ .n_regval_to_nanoscale =
+ ARRAY_SIZE(hmc5883l_regval_to_nanoscale),
+ }
};
static int hmc5843_init(struct hmc5843_data *data)
@@ -508,12 +525,12 @@ static int hmc5843_init(struct hmc5843_data *data)
int ret;
u8 id[3];
- ret = i2c_smbus_read_i2c_block_data(data->client, HMC5843_ID_REG,
- sizeof(id), id);
+ ret = regmap_bulk_read(data->regmap, HMC5843_ID_REG,
+ id, ARRAY_SIZE(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");
+ dev_err(data->dev, "no HMC5843/5883/5883L/5983 sensor\n");
return -ENODEV;
}
@@ -539,27 +556,43 @@ static const struct iio_info hmc5843_info = {
static const unsigned long hmc5843_scan_masks[] = {0x7, 0};
-static int hmc5843_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+
+int hmc5843_common_suspend(struct device *dev)
+{
+ return hmc5843_set_mode(iio_priv(dev_get_drvdata(dev)),
+ HMC5843_MODE_CONVERSION_CONTINUOUS);
+}
+EXPORT_SYMBOL(hmc5843_common_suspend);
+
+int hmc5843_common_resume(struct device *dev)
+{
+ return hmc5843_set_mode(iio_priv(dev_get_drvdata(dev)),
+ HMC5843_MODE_SLEEP);
+}
+EXPORT_SYMBOL(hmc5843_common_resume);
+
+int hmc5843_common_probe(struct device *dev, struct regmap *regmap,
+ enum hmc5843_ids id)
{
struct hmc5843_data *data;
struct iio_dev *indio_dev;
int ret;
- indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
if (indio_dev == NULL)
return -ENOMEM;
+ dev_set_drvdata(dev, indio_dev);
+
/* default settings at probe */
data = iio_priv(indio_dev);
- data->client = client;
- data->variant = &hmc5843_chip_info_tbl[id->driver_data];
+ data->dev = dev;
+ data->regmap = regmap;
+ data->variant = &hmc5843_chip_info_tbl[id];
mutex_init(&data->lock);
- i2c_set_clientdata(client, indio_dev);
+ indio_dev->dev.parent = dev;
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;
@@ -584,10 +617,11 @@ buffer_cleanup:
iio_triggered_buffer_cleanup(indio_dev);
return ret;
}
+EXPORT_SYMBOL(hmc5843_common_probe);
-static int hmc5843_remove(struct i2c_client *client)
+int hmc5843_common_remove(struct device *dev)
{
- struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
iio_device_unregister(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
@@ -597,56 +631,8 @@ static int hmc5843_remove(struct i2c_client *client)
return 0;
}
-
-#ifdef CONFIG_PM_SLEEP
-static int hmc5843_suspend(struct device *dev)
-{
- 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 hmc5843_data *data = iio_priv(i2c_get_clientdata(
- to_i2c_client(dev)));
-
- return hmc5843_set_mode(data, HMC5843_MODE_CONVERSION_CONTINUOUS);
-}
-
-static SIMPLE_DEV_PM_OPS(hmc5843_pm_ops, hmc5843_suspend, hmc5843_resume);
-#define HMC5843_PM_OPS (&hmc5843_pm_ops)
-#else
-#define HMC5843_PM_OPS NULL
-#endif
-
-static const struct i2c_device_id hmc5843_id[] = {
- { "hmc5843", HMC5843_ID },
- { "hmc5883", HMC5883_ID },
- { "hmc5883l", HMC5883L_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,
-};
-module_i2c_driver(hmc5843_driver);
+EXPORT_SYMBOL(hmc5843_common_remove);
MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com>");
-MODULE_DESCRIPTION("HMC5843/5883/5883L driver");
+MODULE_DESCRIPTION("HMC5843/5883/5883L/5983 core driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/iio/magnetometer/hmc5843_i2c.c b/drivers/staging/iio/magnetometer/hmc5843_i2c.c
new file mode 100644
index 000000000000..6acd614cdbc6
--- /dev/null
+++ b/drivers/staging/iio/magnetometer/hmc5843_i2c.c
@@ -0,0 +1,104 @@
+/*
+ * i2c driver for hmc5843/5843/5883/5883l/5983
+ *
+ * Split from hmc5843.c
+ * Copyright (C) Josef Gajdusek <atx@atx.name>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/triggered_buffer.h>
+
+#include "hmc5843.h"
+
+static const struct regmap_range hmc5843_readable_ranges[] = {
+ regmap_reg_range(0, HMC5843_ID_END),
+};
+
+static struct regmap_access_table hmc5843_readable_table = {
+ .yes_ranges = hmc5843_readable_ranges,
+ .n_yes_ranges = ARRAY_SIZE(hmc5843_readable_ranges),
+};
+
+static const struct regmap_range hmc5843_writable_ranges[] = {
+ regmap_reg_range(0, HMC5843_MODE_REG),
+};
+
+static struct regmap_access_table hmc5843_writable_table = {
+ .yes_ranges = hmc5843_writable_ranges,
+ .n_yes_ranges = ARRAY_SIZE(hmc5843_writable_ranges),
+};
+
+static const struct regmap_range hmc5843_volatile_ranges[] = {
+ regmap_reg_range(HMC5843_DATA_OUT_MSB_REGS, HMC5843_STATUS_REG),
+};
+
+static struct regmap_access_table hmc5843_volatile_table = {
+ .yes_ranges = hmc5843_volatile_ranges,
+ .n_yes_ranges = ARRAY_SIZE(hmc5843_volatile_ranges),
+};
+
+static struct regmap_config hmc5843_i2c_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .rd_table = &hmc5843_readable_table,
+ .wr_table = &hmc5843_writable_table,
+ .volatile_table = &hmc5843_volatile_table,
+
+ .cache_type = REGCACHE_RBTREE,
+};
+
+static int hmc5843_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ return hmc5843_common_probe(&client->dev,
+ devm_regmap_init_i2c(client, &hmc5843_i2c_regmap_config),
+ id->driver_data);
+}
+
+static int hmc5843_i2c_remove(struct i2c_client *client)
+{
+ return hmc5843_common_remove(&client->dev);
+}
+
+static const struct i2c_device_id hmc5843_id[] = {
+ { "hmc5843", HMC5843_ID },
+ { "hmc5883", HMC5883_ID },
+ { "hmc5883l", HMC5883L_ID },
+ { "hmc5983", HMC5983_ID },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, hmc5843_id);
+
+static const struct of_device_id hmc5843_of_match[] = {
+ { .compatible = "honeywell,hmc5843", .data = (void *)HMC5843_ID },
+ { .compatible = "honeywell,hmc5883", .data = (void *)HMC5883_ID },
+ { .compatible = "honeywell,hmc5883l", .data = (void *)HMC5883L_ID },
+ { .compatible = "honeywell,hmc5983", .data = (void *)HMC5983_ID },
+ {}
+};
+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_i2c_probe,
+ .remove = hmc5843_i2c_remove,
+};
+module_i2c_driver(hmc5843_driver);
+
+MODULE_AUTHOR("Josef Gajdusek <atx@atx.name>");
+MODULE_DESCRIPTION("HMC5843/5883/5883L/5983 i2c driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/iio/magnetometer/hmc5843_spi.c b/drivers/staging/iio/magnetometer/hmc5843_spi.c
new file mode 100644
index 000000000000..98c4b57101c9
--- /dev/null
+++ b/drivers/staging/iio/magnetometer/hmc5843_spi.c
@@ -0,0 +1,100 @@
+/*
+ * SPI driver for hmc5983
+ *
+ * Copyright (C) Josef Gajdusek <atx@atx.name>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * */
+
+#include <linux/module.h>
+#include <linux/spi/spi.h>
+#include <linux/iio/iio.h>
+
+#include "hmc5843.h"
+
+static const struct regmap_range hmc5843_readable_ranges[] = {
+ regmap_reg_range(0, HMC5843_ID_END),
+};
+
+static struct regmap_access_table hmc5843_readable_table = {
+ .yes_ranges = hmc5843_readable_ranges,
+ .n_yes_ranges = ARRAY_SIZE(hmc5843_readable_ranges),
+};
+
+static const struct regmap_range hmc5843_writable_ranges[] = {
+ regmap_reg_range(0, HMC5843_MODE_REG),
+};
+
+static struct regmap_access_table hmc5843_writable_table = {
+ .yes_ranges = hmc5843_writable_ranges,
+ .n_yes_ranges = ARRAY_SIZE(hmc5843_writable_ranges),
+};
+
+static const struct regmap_range hmc5843_volatile_ranges[] = {
+ regmap_reg_range(HMC5843_DATA_OUT_MSB_REGS, HMC5843_STATUS_REG),
+};
+
+static struct regmap_access_table hmc5843_volatile_table = {
+ .yes_ranges = hmc5843_volatile_ranges,
+ .n_yes_ranges = ARRAY_SIZE(hmc5843_volatile_ranges),
+};
+
+static struct regmap_config hmc5843_spi_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .rd_table = &hmc5843_readable_table,
+ .wr_table = &hmc5843_writable_table,
+ .volatile_table = &hmc5843_volatile_table,
+
+ /* Autoincrement address pointer */
+ .read_flag_mask = 0xc0,
+
+ .cache_type = REGCACHE_RBTREE,
+};
+
+static int hmc5843_spi_probe(struct spi_device *spi)
+{
+ int ret;
+
+ spi->mode = SPI_MODE_3;
+ spi->max_speed_hz = 8000000;
+ spi->bits_per_word = 8;
+ ret = spi_setup(spi);
+ if (ret)
+ return ret;
+
+ return hmc5843_common_probe(&spi->dev,
+ devm_regmap_init_spi(spi, &hmc5843_spi_regmap_config),
+ HMC5983_ID);
+}
+
+static int hmc5843_spi_remove(struct spi_device *spi)
+{
+ return hmc5843_common_remove(&spi->dev);
+}
+
+static const struct spi_device_id hmc5843_id[] = {
+ { "hmc5983", HMC5983_ID },
+ { }
+};
+
+static struct spi_driver hmc5843_driver = {
+ .driver = {
+ .name = "hmc5843",
+ .pm = HMC5843_PM_OPS,
+ .owner = THIS_MODULE,
+ },
+ .id_table = hmc5843_id,
+ .probe = hmc5843_spi_probe,
+ .remove = hmc5843_spi_remove,
+};
+
+module_spi_driver(hmc5843_driver);
+
+MODULE_AUTHOR("Josef Gajdusek <atx@atx.name>");
+MODULE_DESCRIPTION("HMC5983 SPI driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/iio/meter/ade7758_trigger.c b/drivers/staging/iio/meter/ade7758_trigger.c
index 7a94ddd42f59..ea01b8f7a2c3 100644
--- a/drivers/staging/iio/meter/ade7758_trigger.c
+++ b/drivers/staging/iio/meter/ade7758_trigger.c
@@ -21,7 +21,7 @@
static irqreturn_t ade7758_data_rdy_trig_poll(int irq, void *private)
{
disable_irq_nosync(irq);
- iio_trigger_poll(private, iio_get_time_ns());
+ iio_trigger_poll(private);
return IRQ_HANDLED;
}
diff --git a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c
index 26e1ca0b7800..a21b7c514776 100644
--- a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c
+++ b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c
@@ -154,7 +154,7 @@ static irqreturn_t iio_bfin_tmr_trigger_isr(int irq, void *devid)
struct bfin_tmr_state *st = devid;
clear_gptimer_intr(st->t->id);
- iio_trigger_poll(st->trig, 0);
+ iio_trigger_poll(st->trig);
return IRQ_HANDLED;
}
@@ -182,45 +182,40 @@ static int iio_bfin_tmr_trigger_probe(struct platform_device *pdev)
unsigned int config;
int ret;
- st = kzalloc(sizeof(*st), GFP_KERNEL);
- if (st == NULL) {
- ret = -ENOMEM;
- goto out;
- }
+ st = devm_kzalloc(&pdev->dev, sizeof(*st), GFP_KERNEL);
+ if (st == NULL)
+ return -ENOMEM;
st->irq = platform_get_irq(pdev, 0);
if (!st->irq) {
dev_err(&pdev->dev, "No IRQs specified");
- ret = -ENODEV;
- goto out1;
+ return -ENODEV;
}
ret = iio_bfin_tmr_get_number(st->irq);
if (ret < 0)
- goto out1;
+ return ret;
st->timer_num = ret;
st->t = &iio_bfin_timer_code[st->timer_num];
st->trig = iio_trigger_alloc("bfintmr%d", st->timer_num);
- if (!st->trig) {
- ret = -ENOMEM;
- goto out1;
- }
+ if (!st->trig)
+ return -ENOMEM;
st->trig->ops = &iio_bfin_tmr_trigger_ops;
st->trig->dev.groups = iio_bfin_tmr_trigger_attr_groups;
iio_trigger_set_drvdata(st->trig, st);
ret = iio_trigger_register(st->trig);
if (ret)
- goto out2;
+ goto out;
ret = request_irq(st->irq, iio_bfin_tmr_trigger_isr,
0, st->trig->name, st);
if (ret) {
dev_err(&pdev->dev,
"request IRQ-%d failed", st->irq);
- goto out4;
+ goto out1;
}
config = PWM_OUT | PERIOD_CNT | IRQ_ENA;
@@ -260,13 +255,10 @@ static int iio_bfin_tmr_trigger_probe(struct platform_device *pdev)
return 0;
out_free_irq:
free_irq(st->irq, st);
-out4:
- iio_trigger_unregister(st->trig);
-out2:
- iio_trigger_put(st->trig);
out1:
- kfree(st);
+ iio_trigger_unregister(st->trig);
out:
+ iio_trigger_put(st->trig);
return ret;
}
@@ -280,7 +272,6 @@ static int iio_bfin_tmr_trigger_remove(struct platform_device *pdev)
free_irq(st->irq, st);
iio_trigger_unregister(st->trig);
iio_trigger_put(st->trig);
- kfree(st);
return 0;
}
diff --git a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
index 38ecb4bb6e4c..b1aeb88273c9 100644
--- a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
+++ b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
@@ -26,16 +26,22 @@ struct iio_prtc_trigger_info {
struct rtc_device *rtc;
int frequency;
struct rtc_task task;
+ bool state;
};
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)
+ int ret;
+ if (trig_info->frequency == 0 && state)
return -EINVAL;
- dev_info(&trig_info->rtc->dev, "trigger frequency is %d\n",
+ dev_dbg(&trig_info->rtc->dev, "trigger frequency is %d\n",
trig_info->frequency);
- return rtc_irq_set_state(trig_info->rtc, &trig_info->task, state);
+ ret = rtc_irq_set_state(trig_info->rtc, &trig_info->task, state);
+ if (ret == 0)
+ trig_info->state = state;
+
+ return ret;
}
static ssize_t iio_trig_periodic_read_freq(struct device *dev,
@@ -61,7 +67,14 @@ static ssize_t iio_trig_periodic_write_freq(struct device *dev,
if (ret)
goto error_ret;
- ret = rtc_irq_set_freq(trig_info->rtc, &trig_info->task, val);
+ if (val > 0) {
+ ret = rtc_irq_set_freq(trig_info->rtc, &trig_info->task, val);
+ if (ret == 0 && trig_info->state && trig_info->frequency == 0)
+ ret = rtc_irq_set_state(trig_info->rtc, &trig_info->task, 1);
+ } else if (val == 0) {
+ ret = rtc_irq_set_state(trig_info->rtc, &trig_info->task, 0);
+ } else
+ ret = -EINVAL;
if (ret)
goto error_ret;
@@ -93,8 +106,7 @@ static const struct attribute_group *iio_trig_prtc_attr_groups[] = {
static void iio_prtc_trigger_poll(void *private_data)
{
- /* Timestamp is not provided currently */
- iio_trigger_poll(private_data, 0);
+ iio_trigger_poll(private_data);
}
static const struct iio_trigger_ops iio_prtc_trigger_ops = {
@@ -128,8 +140,7 @@ static int iio_trig_periodic_rtc_probe(struct platform_device *dev)
iio_trigger_set_drvdata(trig, trig_info);
trig->ops = &iio_prtc_trigger_ops;
/* RTC access */
- trig_info->rtc
- = rtc_class_open(pdata[i]);
+ trig_info->rtc = rtc_class_open(pdata[i]);
if (trig_info->rtc == NULL) {
ret = -EINVAL;
goto error_free_trig_info;
@@ -199,5 +210,5 @@ static struct platform_driver iio_trig_periodic_rtc_driver = {
module_platform_driver(iio_trig_periodic_rtc_driver);
MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
-MODULE_DESCRIPTION("Periodic realtime clock trigger for the iio subsystem");
+MODULE_DESCRIPTION("Periodic realtime clock trigger for the iio subsystem");
MODULE_LICENSE("GPL v2");