diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
index 6e02c5029152ea0832fdebdfa9bd9aff14188b2d..58ba3330030576e582843a263fa16fd34aafba64 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -210,6 +210,14 @@ Contact:	linux-iio@vger.kernel.org
 Description:
 		Scaled humidity measurement in milli percent.
 
+What:		/sys/bus/iio/devices/iio:deviceX/in_X_mean_raw
+KernelVersion:	3.5
+Contact:	linux-iio@vger.kernel.org
+Description:
+		Averaged raw measurement from channel X. The number of values
+		used for averaging is device specific. The converting rules for
+		normal raw values also applies to the averaged raw values.
+
 What:		/sys/bus/iio/devices/iio:deviceX/in_accel_offset
 What:		/sys/bus/iio/devices/iio:deviceX/in_accel_x_offset
 What:		/sys/bus/iio/devices/iio:deviceX/in_accel_y_offset
diff --git a/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935 b/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935
new file mode 100644
index 0000000000000000000000000000000000000000..6708c5e264aa81875d0eec9c556b8b14429d4c49
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935
@@ -0,0 +1,16 @@
+What		/sys/bus/iio/devices/iio:deviceX/in_proximity_raw
+Date:		March 2014
+KernelVersion:	3.15
+Contact:	Matt Ranostay <mranostay@gmail.com>
+Description:
+		Get the current distance in meters of storm (1km steps)
+		1000-40000 = distance in meters
+
+What		/sys/bus/iio/devices/iio:deviceX/sensor_sensitivity
+Date:		March 2014
+KernelVersion:	3.15
+Contact:	Matt Ranostay <mranostay@gmail.com>
+Description:
+		Show or set the gain boost of the amp, from 0-31 range.
+		18 = indoors (default)
+		14 = outdoors
diff --git a/Documentation/devicetree/bindings/iio/proximity/as3935.txt b/Documentation/devicetree/bindings/iio/proximity/as3935.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ae23dd8da7366f18b9e60f70debbce704f89a927
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/proximity/as3935.txt
@@ -0,0 +1,28 @@
+Austrian Microsystems AS3935 Franklin lightning sensor device driver
+
+Required properties:
+	- compatible: must be "ams,as3935"
+	- reg: SPI chip select number for the device
+	- spi-cpha: SPI Mode 1. Refer to spi/spi-bus.txt for generic SPI
+	slave node bindings.
+	- interrupt-parent : should be the phandle for the interrupt controller
+	- interrupts : the sole interrupt generated by the device
+
+	Refer to interrupt-controller/interrupts.txt for generic
+	interrupt client node bindings.
+
+Optional properties:
+	- ams,tuning-capacitor-pf: Calibration tuning capacitor stepping
+	  value 0 - 120pF. This will require using the calibration data from
+	  the manufacturer.
+
+Example:
+
+as3935@0 {
+	compatible = "ams,as3935";
+	reg = <0>;
+	spi-cpha;
+	interrupt-parent = <&gpio1>;
+	interrupts = <16 1>;
+	ams,tuning-capacitor-pf = <80>;
+};
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index abc308083acb204c7625c5d53ed58d546c65f755..7e88bc6195653ac148c3e93ade52cce9ace87619 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -13,6 +13,7 @@ allwinner	Allwinner Technology Co., Ltd.
 altr	Altera Corp.
 amcc	Applied Micro Circuits Corporation (APM, formally AMCC)
 amd	Advanced Micro Devices (AMD), Inc.
+ams	AMS AG
 amstaos	AMS-Taos Inc.
 apm	Applied Micro Circuits Corporation (APM)
 arm	ARM Ltd.
diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig
index 5dd0e120a504cd68cf096c1304512af112c97862..743485e4d6f83c28de0729509b8951b9f112a4eb 100644
--- a/drivers/iio/Kconfig
+++ b/drivers/iio/Kconfig
@@ -74,6 +74,7 @@ if IIO_TRIGGER
    source "drivers/iio/trigger/Kconfig"
 endif #IIO_TRIGGER
 source "drivers/iio/pressure/Kconfig"
+source "drivers/iio/proximity/Kconfig"
 source "drivers/iio/temperature/Kconfig"
 
 endif # IIO
diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile
index 887d39090d7568391d059bdf9f30902a6123cd25..698afc2d17ce84c62e8e7fea4473558505d11808 100644
--- a/drivers/iio/Makefile
+++ b/drivers/iio/Makefile
@@ -24,5 +24,6 @@ obj-y += light/
 obj-y += magnetometer/
 obj-y += orientation/
 obj-y += pressure/
+obj-y += proximity/
 obj-y += temperature/
 obj-y += trigger/
diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c
index 38caedc76b98f20520f9be751fabc15e90b03793..a2abf7c2ce3be4cbd0cdcbb8dd2481035651d3bc 100644
--- a/drivers/iio/accel/st_accel_core.c
+++ b/drivers/iio/accel/st_accel_core.c
@@ -459,6 +459,8 @@ int st_accel_common_probe(struct iio_dev *indio_dev,
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->info = &accel_info;
 
+	st_sensors_power_enable(indio_dev);
+
 	err = st_sensors_check_device_support(indio_dev,
 				ARRAY_SIZE(st_accel_sensors), st_accel_sensors);
 	if (err < 0)
@@ -496,6 +498,9 @@ int st_accel_common_probe(struct iio_dev *indio_dev,
 	if (err)
 		goto st_accel_device_register_error;
 
+	dev_info(&indio_dev->dev, "registered accelerometer %s\n",
+		 indio_dev->name);
+
 	return 0;
 
 st_accel_device_register_error:
@@ -512,6 +517,8 @@ void st_accel_common_remove(struct iio_dev *indio_dev)
 {
 	struct st_sensor_data *adata = iio_priv(indio_dev);
 
+	st_sensors_power_disable(indio_dev);
+
 	iio_device_unregister(indio_dev);
 	if (adata->get_irq_data_ready(indio_dev) > 0)
 		st_sensors_deallocate_trigger(indio_dev);
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index d86196cfe4b47091add5d756da6d3dbf7fded9eb..6cbf34a90c04b21fbb56cae6f711a3db386ef173 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -96,6 +96,17 @@ config AD7923
 	  To compile this driver as a module, choose M here: the
 	  module will be called ad7923.
 
+config AD799X
+	tristate "Analog Devices AD799x ADC driver"
+	depends on I2C
+	select IIO_BUFFER
+	select IIO_TRIGGERED_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 AT91_ADC
 	tristate "Atmel AT91 ADC"
 	depends on ARCH_AT91
@@ -107,7 +118,7 @@ config AT91_ADC
 
 config EXYNOS_ADC
 	bool "Exynos ADC driver support"
-	depends on OF
+	depends on ARCH_EXYNOS || (OF && COMPILE_TEST)
 	help
 	  Core support for the ADC block found in the Samsung EXYNOS series
 	  of SoCs for drivers such as the touchscreen and hwmon to use to share
@@ -146,11 +157,12 @@ config MCP320X
 	  called mcp320x.
 
 config MCP3422
-	tristate "Microchip Technology MCP3422/3/4 driver"
+	tristate "Microchip Technology MCP3422/3/4/6/7/8 driver"
 	depends on I2C
 	help
-	  Say yes here to build support for Microchip Technology's MCP3422,
-	  MCP3423 or MCP3424 analog to digital converters.
+	  Say yes here to build support for Microchip Technology's
+	  MCP3422, MCP3423, MCP3424, MCP3426, MCP3427 or MCP3428
+	  analog to digital converters.
 
 	  This driver can also be built as a module. If so, the module will be
 	  called mcp3422.
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index ab346d88c68874e2ac06dc6f2911ef1ec6cf0f25..9d60f2deaaaf276d8b6c0ee5134feb520f3dec9c 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_AD7476) += ad7476.o
 obj-$(CONFIG_AD7791) += ad7791.o
 obj-$(CONFIG_AD7793) += ad7793.o
 obj-$(CONFIG_AD7887) += ad7887.o
+obj-$(CONFIG_AD799X) += ad799x.o
 obj-$(CONFIG_AT91_ADC) += at91_adc.o
 obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
 obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
diff --git a/drivers/staging/iio/adc/ad799x_core.c b/drivers/iio/adc/ad799x.c
similarity index 81%
rename from drivers/staging/iio/adc/ad799x_core.c
rename to drivers/iio/adc/ad799x.c
index 979ec77d6c2d1b17c9e644f720ad953ec9364e5a..16a8b14b1921746b9449ee0645d231e346655819 100644
--- a/drivers/staging/iio/adc/ad799x_core.c
+++ b/drivers/iio/adc/ad799x.c
@@ -37,8 +37,144 @@
 #include <linux/iio/sysfs.h>
 #include <linux/iio/events.h>
 #include <linux/iio/buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
 
-#include "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_REG(x)			((x) * 3 + 0x4)
+#define AD7998_DATAHIGH_REG(x)			((x) * 3 + 0x5)
+#define AD7998_HYST_REG(x)			((x) * 3 + 0x6)
+
+#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_chip_info - chip specific 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;
+	struct regulator		*vref;
+	unsigned			id;
+	u16				config;
+
+	u8				*rx_buf;
+	unsigned int			transfer_size;
+};
+
+/**
+ * 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);
+	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;
+
+	iio_push_to_buffers_with_timestamp(indio_dev, st->rx_buf,
+			iio_get_time_ns());
+out:
+	iio_trigger_notify_done(indio_dev->trig);
+
+	return IRQ_HANDLED;
+}
 
 /*
  * ad799x register access by I2C
@@ -578,7 +714,8 @@ static int ad799x_probe(struct i2c_client *client,
 	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);
+	ret = iio_triggered_buffer_setup(indio_dev, NULL,
+		&ad799x_trigger_handler, NULL);
 	if (ret)
 		goto error_disable_reg;
 
@@ -601,7 +738,7 @@ static int ad799x_probe(struct i2c_client *client,
 	return 0;
 
 error_cleanup_ring:
-	ad799x_ring_cleanup(indio_dev);
+	iio_triggered_buffer_cleanup(indio_dev);
 error_disable_reg:
 	if (!IS_ERR(st->vref))
 		regulator_disable(st->vref);
@@ -618,7 +755,7 @@ static int ad799x_remove(struct i2c_client *client)
 
 	iio_device_unregister(indio_dev);
 
-	ad799x_ring_cleanup(indio_dev);
+	iio_triggered_buffer_cleanup(indio_dev);
 	if (!IS_ERR(st->vref))
 		regulator_disable(st->vref);
 	if (!IS_ERR(st->reg))
diff --git a/drivers/iio/adc/mcp3422.c b/drivers/iio/adc/mcp3422.c
index 47dcb34ff44c47f6317a62c99e025df6eb6b27f6..51672256072bc8db2778e6c60982f320c680f3d4 100644
--- a/drivers/iio/adc/mcp3422.c
+++ b/drivers/iio/adc/mcp3422.c
@@ -1,10 +1,11 @@
 /*
- * mcp3422.c - driver for the Microchip mcp3422/3/4 chip family
+ * mcp3422.c - driver for the Microchip mcp3422/3/4/6/7/8 chip family
  *
  * Copyright (C) 2013, Angelo Compagnucci
  * Author: Angelo Compagnucci <angelo.compagnucci@gmail.com>
  *
  * Datasheet: http://ww1.microchip.com/downloads/en/devicedoc/22088b.pdf
+ *            http://ww1.microchip.com/downloads/en/DeviceDoc/22226a.pdf
  *
  * This driver exports the value of analog input voltage to sysfs, the
  * voltage unit is nV.
@@ -96,6 +97,7 @@ static const int mcp3422_sign_extend[4] = {
 /* Client data (each client gets its own) */
 struct mcp3422 {
 	struct i2c_client *i2c;
+	u8 id;
 	u8 config;
 	u8 pga[4];
 	struct mutex lock;
@@ -238,6 +240,8 @@ static int mcp3422_write_raw(struct iio_dev *iio,
 			temp = MCP3422_SRATE_15;
 			break;
 		case 3:
+			if (adc->id > 4)
+				return -EINVAL;
 			temp = MCP3422_SRATE_3;
 			break;
 		default:
@@ -271,6 +275,17 @@ static int mcp3422_write_raw_get_fmt(struct iio_dev *indio_dev,
 	}
 }
 
+static ssize_t mcp3422_show_samp_freqs(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct mcp3422 *adc = iio_priv(dev_to_iio_dev(dev));
+
+	if (adc->id > 4)
+		return sprintf(buf, "240 60 15\n");
+
+	return sprintf(buf, "240 60 15 3\n");
+}
+
 static ssize_t mcp3422_show_scales(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
@@ -284,12 +299,13 @@ static ssize_t mcp3422_show_scales(struct device *dev,
 		mcp3422_scales[sample_rate][3]);
 }
 
-static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("240 60 15 3");
+static IIO_DEVICE_ATTR(sampling_frequency_available, S_IRUGO,
+		mcp3422_show_samp_freqs, NULL, 0);
 static IIO_DEVICE_ATTR(in_voltage_scale_available, S_IRUGO,
 		mcp3422_show_scales, NULL, 0);
 
 static struct attribute *mcp3422_attributes[] = {
-	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
+	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
 	&iio_dev_attr_in_voltage_scale_available.dev_attr.attr,
 	NULL,
 };
@@ -335,6 +351,7 @@ static int mcp3422_probe(struct i2c_client *client,
 
 	adc = iio_priv(indio_dev);
 	adc->i2c = client;
+	adc->id = (u8)(id->driver_data);
 
 	mutex_init(&adc->lock);
 
@@ -343,13 +360,16 @@ static int mcp3422_probe(struct i2c_client *client,
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->info = &mcp3422_info;
 
-	switch ((unsigned int)(id->driver_data)) {
+	switch (adc->id) {
 	case 2:
 	case 3:
+	case 6:
+	case 7:
 		indio_dev->channels = mcp3422_channels;
 		indio_dev->num_channels = ARRAY_SIZE(mcp3422_channels);
 		break;
 	case 4:
+	case 8:
 		indio_dev->channels = mcp3424_channels;
 		indio_dev->num_channels = ARRAY_SIZE(mcp3424_channels);
 		break;
@@ -375,6 +395,9 @@ static const struct i2c_device_id mcp3422_id[] = {
 	{ "mcp3422", 2 },
 	{ "mcp3423", 3 },
 	{ "mcp3424", 4 },
+	{ "mcp3426", 6 },
+	{ "mcp3427", 7 },
+	{ "mcp3428", 8 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, mcp3422_id);
@@ -399,5 +422,5 @@ static struct i2c_driver mcp3422_driver = {
 module_i2c_driver(mcp3422_driver);
 
 MODULE_AUTHOR("Angelo Compagnucci <angelo.compagnucci@gmail.com>");
-MODULE_DESCRIPTION("Microchip mcp3422/3/4 driver");
+MODULE_DESCRIPTION("Microchip mcp3422/3/4/6/7/8 driver");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c
index 7ba1ef27021323ec82ccb8a2cb3242795bfb0116..e8b932fed70ecb4b97ac5eeb044a6fb0c41cfcdd 100644
--- a/drivers/iio/common/st_sensors/st_sensors_core.c
+++ b/drivers/iio/common/st_sensors/st_sensors_core.c
@@ -13,6 +13,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/iio/iio.h>
+#include <linux/regulator/consumer.h>
 #include <asm/unaligned.h>
 
 #include <linux/iio/common/st_sensors.h>
@@ -198,6 +199,42 @@ int st_sensors_set_axis_enable(struct iio_dev *indio_dev, u8 axis_enable)
 }
 EXPORT_SYMBOL(st_sensors_set_axis_enable);
 
+void st_sensors_power_enable(struct iio_dev *indio_dev)
+{
+	struct st_sensor_data *pdata = iio_priv(indio_dev);
+	int err;
+
+	/* Regulators not mandatory, but if requested we should enable them. */
+	pdata->vdd = devm_regulator_get_optional(indio_dev->dev.parent, "vdd");
+	if (!IS_ERR(pdata->vdd)) {
+		err = regulator_enable(pdata->vdd);
+		if (err != 0)
+			dev_warn(&indio_dev->dev,
+				 "Failed to enable specified Vdd supply\n");
+	}
+
+	pdata->vdd_io = devm_regulator_get_optional(indio_dev->dev.parent, "vddio");
+	if (!IS_ERR(pdata->vdd_io)) {
+		err = regulator_enable(pdata->vdd_io);
+		if (err != 0)
+			dev_warn(&indio_dev->dev,
+				 "Failed to enable specified Vdd_IO supply\n");
+	}
+}
+EXPORT_SYMBOL(st_sensors_power_enable);
+
+void st_sensors_power_disable(struct iio_dev *indio_dev)
+{
+	struct st_sensor_data *pdata = iio_priv(indio_dev);
+
+	if (!IS_ERR(pdata->vdd))
+		regulator_disable(pdata->vdd);
+
+	if (!IS_ERR(pdata->vdd_io))
+		regulator_disable(pdata->vdd_io);
+}
+EXPORT_SYMBOL(st_sensors_power_disable);
+
 static int st_sensors_set_drdy_int_pin(struct iio_dev *indio_dev,
 				       struct st_sensors_platform_data *pdata)
 {
diff --git a/drivers/iio/gyro/itg3200_core.c b/drivers/iio/gyro/itg3200_core.c
index 4d3f3b92b361ef06ec57649f664205201b0cfc34..8295e318399f9874ccde4f4429a001141a4004be 100644
--- a/drivers/iio/gyro/itg3200_core.c
+++ b/drivers/iio/gyro/itg3200_core.c
@@ -110,8 +110,6 @@ static int itg3200_read_raw(struct iio_dev *indio_dev,
 	default:
 		return -EINVAL;
 	}
-
-	return ret;
 }
 
 static ssize_t itg3200_read_frequency(struct device *dev,
diff --git a/drivers/iio/gyro/st_gyro_core.c b/drivers/iio/gyro/st_gyro_core.c
index a8e174a47bc409cc22ece45c5a971ca3fe14f37d..ed74a906998953de9c97461a7f137323eb30ed5f 100644
--- a/drivers/iio/gyro/st_gyro_core.c
+++ b/drivers/iio/gyro/st_gyro_core.c
@@ -311,6 +311,8 @@ int st_gyro_common_probe(struct iio_dev *indio_dev,
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->info = &gyro_info;
 
+	st_sensors_power_enable(indio_dev);
+
 	err = st_sensors_check_device_support(indio_dev,
 				ARRAY_SIZE(st_gyro_sensors), st_gyro_sensors);
 	if (err < 0)
@@ -344,6 +346,9 @@ int st_gyro_common_probe(struct iio_dev *indio_dev,
 	if (err)
 		goto st_gyro_device_register_error;
 
+	dev_info(&indio_dev->dev, "registered gyroscope %s\n",
+		 indio_dev->name);
+
 	return 0;
 
 st_gyro_device_register_error:
@@ -360,6 +365,8 @@ void st_gyro_common_remove(struct iio_dev *indio_dev)
 {
 	struct st_sensor_data *gdata = iio_priv(indio_dev);
 
+	st_sensors_power_disable(indio_dev);
+
 	iio_device_unregister(indio_dev);
 	if (gdata->get_irq_data_ready(indio_dev) > 0)
 		st_sensors_deallocate_trigger(indio_dev);
diff --git a/drivers/iio/imu/inv_mpu6050/Kconfig b/drivers/iio/imu/inv_mpu6050/Kconfig
index 361b2328453d478cd5ba945e91b9c242310b6119..2d0608ba88d7d6e375ae3b0f9c94853c4af84015 100644
--- a/drivers/iio/imu/inv_mpu6050/Kconfig
+++ b/drivers/iio/imu/inv_mpu6050/Kconfig
@@ -9,6 +9,8 @@ config INV_MPU6050_IIO
 	select IIO_TRIGGERED_BUFFER
 	help
 	  This driver supports the Invensense MPU6050 devices.
+	  This driver can also support MPU6500 in MPU6050 compatibility mode
+	  and also in MPU6500 mode with some limitations.
 	  It is a gyroscope/accelerometer combo device.
 	  This driver can be built as a module. The module will be called
 	  inv-mpu6050.
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
index cb9f96b446a55cd138f129db3443d44821b32781..af287bf719154c2bbe75c7ae8a7fbc2bd88f4067 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
@@ -764,6 +764,7 @@ static SIMPLE_DEV_PM_OPS(inv_mpu_pmops, inv_mpu_suspend, inv_mpu_resume);
  */
 static const struct i2c_device_id inv_mpu_id[] = {
 	{"mpu6050", INV_MPU6050},
+	{"mpu6500", INV_MPU6500},
 	{}
 };
 
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
index 0ab382be1e64198fbdce8edba42347c0740ce185..e7799315d4dc1c4167338a922215e3404bb389d8 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
@@ -59,6 +59,7 @@ struct inv_mpu6050_reg_map {
 /*device enum */
 enum inv_devices {
 	INV_MPU6050,
+	INV_MPU6500,
 	INV_NUM_PARTS
 };
 
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index ede16aec20fbd68ec01f729aaffa4543e02a8f0c..184444db62acaca683c8ebce22b0870c1ff7ebac 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -340,7 +340,7 @@ ssize_t iio_enum_read(struct iio_dev *indio_dev,
 	else if (i >= e->num_items)
 		return -EINVAL;
 
-	return sprintf(buf, "%s\n", e->items[i]);
+	return snprintf(buf, PAGE_SIZE, "%s\n", e->items[i]);
 }
 EXPORT_SYMBOL_GPL(iio_enum_read);
 
@@ -716,6 +716,8 @@ static int iio_device_add_info_mask_type(struct iio_dev *indio_dev,
 	int i, ret, attrcount = 0;
 
 	for_each_set_bit(i, infomask, sizeof(infomask)*8) {
+		if (i >= ARRAY_SIZE(iio_chan_info_postfix))
+			return -EINVAL;
 		ret = __iio_add_chan_devattr(iio_chan_info_postfix[i],
 					     chan,
 					     &iio_read_channel_info,
@@ -820,7 +822,7 @@ static ssize_t iio_show_dev_name(struct device *dev,
 				 char *buf)
 {
 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	return sprintf(buf, "%s\n", indio_dev->name);
+	return snprintf(buf, PAGE_SIZE, "%s\n", indio_dev->name);
 }
 
 static DEVICE_ATTR(name, S_IRUGO, iio_show_dev_name, NULL);
diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c
index ea6e06b9c7d42954cf6eb0d5ab86f18734e828b4..dddfb0f90d342e5b324bba657c5d194df6205a2d 100644
--- a/drivers/iio/industrialio-event.c
+++ b/drivers/iio/industrialio-event.c
@@ -321,7 +321,9 @@ static int iio_device_add_event(struct iio_dev *indio_dev,
 	char *postfix;
 	int ret;
 
-	for_each_set_bit(i, mask, sizeof(*mask)) {
+	for_each_set_bit(i, mask, sizeof(*mask)*8) {
+		if (i >= ARRAY_SIZE(iio_ev_info_text))
+			return -EINVAL;
 		postfix = kasprintf(GFP_KERNEL, "%s_%s_%s",
 				iio_ev_type_text[type], iio_ev_dir_text[dir],
 				iio_ev_info_text[i]);
diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
index 0cf5f8e06cfcc6b6bc8c059871e153a391cbd122..adeba5a0ecf70ff79ed4e3ed653ee6e4bf27b0ca 100644
--- a/drivers/iio/inkern.c
+++ b/drivers/iio/inkern.c
@@ -443,6 +443,24 @@ int iio_read_channel_raw(struct iio_channel *chan, int *val)
 }
 EXPORT_SYMBOL_GPL(iio_read_channel_raw);
 
+int iio_read_channel_average_raw(struct iio_channel *chan, int *val)
+{
+	int ret;
+
+	mutex_lock(&chan->indio_dev->info_exist_lock);
+	if (chan->indio_dev->info == NULL) {
+		ret = -ENODEV;
+		goto err_unlock;
+	}
+
+	ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_AVERAGE_RAW);
+err_unlock:
+	mutex_unlock(&chan->indio_dev->info_exist_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(iio_read_channel_average_raw);
+
 static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan,
 	int raw, int *processed, unsigned int scale)
 {
diff --git a/drivers/iio/magnetometer/Kconfig b/drivers/iio/magnetometer/Kconfig
index d86d226dcd67e09b585652ef983c9ccb038cdb99..05a364c543f851bae06bd35733676b7491a997fe 100644
--- a/drivers/iio/magnetometer/Kconfig
+++ b/drivers/iio/magnetometer/Kconfig
@@ -11,7 +11,8 @@ config AK8975
 	depends on GPIOLIB
 	help
 	  Say yes here to build support for Asahi Kasei AK8975 3-Axis
-	  Magnetometer.
+	  Magnetometer. This driver can also support AK8963, if i2c
+	  device name is identified as ak8963.
 
 	  To compile this driver as a module, choose M here: the module
 	  will be called ak8975.
diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c
index 74866d1efd1b8a646d2add6f5b5000cfbc52b925..f5c1d41bf39f550c7ccbf4464d11bc6a877009dc 100644
--- a/drivers/iio/magnetometer/ak8975.c
+++ b/drivers/iio/magnetometer/ak8975.c
@@ -31,6 +31,7 @@
 #include <linux/bitops.h>
 #include <linux/gpio.h>
 #include <linux/of_gpio.h>
+#include <linux/acpi.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
@@ -85,7 +86,14 @@
 #define AK8975_MAX_CONVERSION_TIMEOUT	500
 #define AK8975_CONVERSION_DONE_POLL_TIME 10
 #define AK8975_DATA_READY_TIMEOUT	((100*HZ)/1000)
-#define RAW_TO_GAUSS(asa) ((((asa) + 128) * 3000) / 256)
+#define RAW_TO_GAUSS_8975(asa) ((((asa) + 128) * 3000) / 256)
+#define RAW_TO_GAUSS_8963(asa) ((((asa) + 128) * 6000) / 256)
+
+/* Compatible Asahi Kasei Compass parts */
+enum asahi_compass_chipset {
+	AK8975,
+	AK8963,
+};
 
 /*
  * Per-instance context data for the device.
@@ -101,6 +109,7 @@ struct ak8975_data {
 	int			eoc_irq;
 	wait_queue_head_t	data_ready_queue;
 	unsigned long		flags;
+	enum asahi_compass_chipset chipset;
 };
 
 static const int ak8975_index_to_reg[] = {
@@ -272,9 +281,21 @@ static int ak8975_setup(struct i2c_client *client)
  * Since ASA doesn't change, we cache the resultant scale factor into the
  * device context in ak8975_setup().
  */
-	data->raw_to_gauss[0] = RAW_TO_GAUSS(data->asa[0]);
-	data->raw_to_gauss[1] = RAW_TO_GAUSS(data->asa[1]);
-	data->raw_to_gauss[2] = RAW_TO_GAUSS(data->asa[2]);
+	if (data->chipset == AK8963) {
+		/*
+		 * H range is +-8190 and magnetometer range is +-4912.
+		 * So HuT using the above explanation for 8975,
+		 * 4912/8190 = ~ 6/10.
+		 * So the Hadj should use 6/10 instead of 3/10.
+		 */
+		data->raw_to_gauss[0] = RAW_TO_GAUSS_8963(data->asa[0]);
+		data->raw_to_gauss[1] = RAW_TO_GAUSS_8963(data->asa[1]);
+		data->raw_to_gauss[2] = RAW_TO_GAUSS_8963(data->asa[2]);
+	} else {
+		data->raw_to_gauss[0] = RAW_TO_GAUSS_8975(data->asa[0]);
+		data->raw_to_gauss[1] = RAW_TO_GAUSS_8975(data->asa[1]);
+		data->raw_to_gauss[2] = RAW_TO_GAUSS_8975(data->asa[2]);
+	}
 
 	return 0;
 }
@@ -455,6 +476,27 @@ static const struct iio_info ak8975_info = {
 	.driver_module = THIS_MODULE,
 };
 
+static const struct acpi_device_id ak_acpi_match[] = {
+	{"AK8975", AK8975},
+	{"AK8963", AK8963},
+	{"INVN6500", AK8963},
+	{ },
+};
+MODULE_DEVICE_TABLE(acpi, ak_acpi_match);
+
+static char *ak8975_match_acpi_device(struct device *dev,
+				enum asahi_compass_chipset *chipset)
+{
+	const struct acpi_device_id *id;
+
+	id = acpi_match_device(dev->driver->acpi_match_table, dev);
+	if (!id)
+		return NULL;
+	*chipset = (int)id->driver_data;
+
+	return (char *)dev_name(dev);
+}
+
 static int ak8975_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
@@ -462,6 +504,7 @@ static int ak8975_probe(struct i2c_client *client,
 	struct iio_dev *indio_dev;
 	int eoc_gpio;
 	int err;
+	char *name = NULL;
 
 	/* Grab and set up the supplied GPIO. */
 	if (client->dev.platform_data)
@@ -499,6 +542,19 @@ static int ak8975_probe(struct i2c_client *client,
 	data->eoc_gpio = eoc_gpio;
 	data->eoc_irq = 0;
 
+	/* id will be NULL when enumerated via ACPI */
+	if (id) {
+		data->chipset =
+			(enum asahi_compass_chipset)(id->driver_data);
+		name = (char *) id->name;
+	} else if (ACPI_HANDLE(&client->dev))
+		name = ak8975_match_acpi_device(&client->dev, &data->chipset);
+	else {
+		err = -ENOSYS;
+		goto exit_free_iio;
+	}
+	dev_dbg(&client->dev, "Asahi compass chip %s\n", name);
+
 	/* Perform some basic start-of-day setup of the device. */
 	err = ak8975_setup(client);
 	if (err < 0) {
@@ -515,7 +571,7 @@ static int ak8975_probe(struct i2c_client *client,
 	indio_dev->info = &ak8975_info;
 	indio_dev->name = id->name;
 	indio_dev->modes = INDIO_DIRECT_MODE;
-
+	indio_dev->name = name;
 	err = iio_device_register(indio_dev);
 	if (err < 0)
 		goto exit_free_iio;
@@ -552,7 +608,8 @@ static int ak8975_remove(struct i2c_client *client)
 }
 
 static const struct i2c_device_id ak8975_id[] = {
-	{"ak8975", 0},
+	{"ak8975", AK8975},
+	{"ak8963", AK8963},
 	{}
 };
 
@@ -569,6 +626,7 @@ static struct i2c_driver ak8975_driver = {
 	.driver = {
 		.name	= "ak8975",
 		.of_match_table = ak8975_of_match,
+		.acpi_match_table = ACPI_PTR(ak_acpi_match),
 	},
 	.probe		= ak8975_probe,
 	.remove		= ak8975_remove,
diff --git a/drivers/iio/magnetometer/st_magn_core.c b/drivers/iio/magnetometer/st_magn_core.c
index 52bbcfa1e07795208b45633ced62de0015772b74..240a21dd0c6111457ce171d37b5d43fa9b5b0316 100644
--- a/drivers/iio/magnetometer/st_magn_core.c
+++ b/drivers/iio/magnetometer/st_magn_core.c
@@ -355,6 +355,8 @@ int st_magn_common_probe(struct iio_dev *indio_dev,
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->info = &magn_info;
 
+	st_sensors_power_enable(indio_dev);
+
 	err = st_sensors_check_device_support(indio_dev,
 				ARRAY_SIZE(st_magn_sensors), st_magn_sensors);
 	if (err < 0)
@@ -387,6 +389,9 @@ int st_magn_common_probe(struct iio_dev *indio_dev,
 	if (err)
 		goto st_magn_device_register_error;
 
+	dev_info(&indio_dev->dev, "registered magnetometer %s\n",
+		 indio_dev->name);
+
 	return 0;
 
 st_magn_device_register_error:
@@ -403,6 +408,8 @@ void st_magn_common_remove(struct iio_dev *indio_dev)
 {
 	struct st_sensor_data *mdata = iio_priv(indio_dev);
 
+	st_sensors_power_disable(indio_dev);
+
 	iio_device_unregister(indio_dev);
 	if (mdata->get_irq_data_ready(indio_dev) > 0)
 		st_sensors_deallocate_trigger(indio_dev);
diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c
index 7418768ed49c62ef830d071f84f7506729129369..cd7e01f3a93b5fbfd59ade63de23fc8b11f436cc 100644
--- a/drivers/iio/pressure/st_pressure_core.c
+++ b/drivers/iio/pressure/st_pressure_core.c
@@ -23,7 +23,6 @@
 #include <linux/iio/sysfs.h>
 #include <linux/iio/trigger.h>
 #include <linux/iio/buffer.h>
-#include <linux/regulator/consumer.h>
 #include <asm/unaligned.h>
 
 #include <linux/iio/common/st_sensors.h>
@@ -387,40 +386,6 @@ static const struct iio_trigger_ops st_press_trigger_ops = {
 #define ST_PRESS_TRIGGER_OPS NULL
 #endif
 
-static void st_press_power_enable(struct iio_dev *indio_dev)
-{
-	struct st_sensor_data *pdata = iio_priv(indio_dev);
-	int err;
-
-	/* Regulators not mandatory, but if requested we should enable them. */
-	pdata->vdd = devm_regulator_get_optional(&indio_dev->dev, "vdd");
-	if (!IS_ERR(pdata->vdd)) {
-		err = regulator_enable(pdata->vdd);
-		if (err != 0)
-			dev_warn(&indio_dev->dev,
-				 "Failed to enable specified Vdd supply\n");
-	}
-
-	pdata->vdd_io = devm_regulator_get_optional(&indio_dev->dev, "vddio");
-	if (!IS_ERR(pdata->vdd_io)) {
-		err = regulator_enable(pdata->vdd_io);
-		if (err != 0)
-			dev_warn(&indio_dev->dev,
-				 "Failed to enable specified Vdd_IO supply\n");
-	}
-}
-
-static void st_press_power_disable(struct iio_dev *indio_dev)
-{
-	struct st_sensor_data *pdata = iio_priv(indio_dev);
-
-	if (!IS_ERR(pdata->vdd))
-		regulator_disable(pdata->vdd);
-
-	if (!IS_ERR(pdata->vdd_io))
-		regulator_disable(pdata->vdd_io);
-}
-
 int st_press_common_probe(struct iio_dev *indio_dev,
 				struct st_sensors_platform_data *plat_data)
 {
@@ -431,7 +396,7 @@ int st_press_common_probe(struct iio_dev *indio_dev,
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->info = &press_info;
 
-	st_press_power_enable(indio_dev);
+	st_sensors_power_enable(indio_dev);
 
 	err = st_sensors_check_device_support(indio_dev,
 					      ARRAY_SIZE(st_press_sensors),
@@ -474,6 +439,9 @@ int st_press_common_probe(struct iio_dev *indio_dev,
 	if (err)
 		goto st_press_device_register_error;
 
+	dev_info(&indio_dev->dev, "registered pressure sensor %s\n",
+		 indio_dev->name);
+
 	return err;
 
 st_press_device_register_error:
@@ -490,7 +458,7 @@ void st_press_common_remove(struct iio_dev *indio_dev)
 {
 	struct st_sensor_data *pdata = iio_priv(indio_dev);
 
-	st_press_power_disable(indio_dev);
+	st_sensors_power_disable(indio_dev);
 
 	iio_device_unregister(indio_dev);
 	if (pdata->get_irq_data_ready(indio_dev) > 0)
diff --git a/drivers/iio/proximity/Kconfig b/drivers/iio/proximity/Kconfig
new file mode 100644
index 0000000000000000000000000000000000000000..0c8cdf58f6a19b5aea05a1205489983c0d1c0d29
--- /dev/null
+++ b/drivers/iio/proximity/Kconfig
@@ -0,0 +1,19 @@
+#
+# Proximity sensors
+#
+
+menu "Lightning sensors"
+
+config AS3935
+	tristate "AS3935 Franklin lightning sensor"
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
+	depends on SPI
+	help
+	  Say Y here to build SPI interface support for the Austrian
+	  Microsystems AS3935 lightning detection sensor.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called as3935
+
+endmenu
diff --git a/drivers/iio/proximity/Makefile b/drivers/iio/proximity/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..743adee1c8bff96fffe46f2bb7ab991aa37afaa0
--- /dev/null
+++ b/drivers/iio/proximity/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for IIO proximity sensors
+#
+
+# When adding new entries keep the list in alphabetical order
+obj-$(CONFIG_AS3935)		+= as3935.o
diff --git a/drivers/iio/proximity/as3935.c b/drivers/iio/proximity/as3935.c
new file mode 100644
index 0000000000000000000000000000000000000000..bf677bfe8eb2c5d647195d1edff82d4108110ae6
--- /dev/null
+++ b/drivers/iio/proximity/as3935.c
@@ -0,0 +1,456 @@
+/*
+ * as3935.c - Support for AS3935 Franklin lightning sensor
+ *
+ * Copyright (C) 2014 Matt Ranostay <mranostay@gmail.com>
+ *
+ * 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
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/workqueue.h>
+#include <linux/mutex.h>
+#include <linux/err.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/spi/spi.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/of_gpio.h>
+
+
+#define AS3935_AFE_GAIN		0x00
+#define AS3935_AFE_MASK		0x3F
+#define AS3935_AFE_GAIN_MAX	0x1F
+#define AS3935_AFE_PWR_BIT	BIT(0)
+
+#define AS3935_INT		0x03
+#define AS3935_INT_MASK		0x07
+#define AS3935_EVENT_INT	BIT(3)
+#define AS3935_NOISE_INT	BIT(1)
+
+#define AS3935_DATA		0x07
+#define AS3935_DATA_MASK	0x3F
+
+#define AS3935_TUNE_CAP		0x08
+#define AS3935_CALIBRATE	0x3D
+
+#define AS3935_WRITE_DATA	BIT(15)
+#define AS3935_READ_DATA	BIT(14)
+#define AS3935_ADDRESS(x)	((x) << 8)
+
+#define MAX_PF_CAP		120
+#define TUNE_CAP_DIV		8
+
+struct as3935_state {
+	struct spi_device *spi;
+	struct iio_trigger *trig;
+	struct mutex lock;
+	struct delayed_work work;
+
+	u32 tune_cap;
+	u8 buf[2] ____cacheline_aligned;
+};
+
+static const struct iio_chan_spec as3935_channels[] = {
+	{
+		.type           = IIO_PROXIMITY,
+		.info_mask_separate =
+			BIT(IIO_CHAN_INFO_RAW) |
+			BIT(IIO_CHAN_INFO_PROCESSED),
+		.scan_index     = 0,
+		.scan_type = {
+			.sign           = 'u',
+			.realbits       = 6,
+			.storagebits    = 8,
+		},
+	},
+	IIO_CHAN_SOFT_TIMESTAMP(1),
+};
+
+static int as3935_read(struct as3935_state *st, unsigned int reg, int *val)
+{
+	u8 cmd;
+	int ret;
+
+	cmd = (AS3935_READ_DATA | AS3935_ADDRESS(reg)) >> 8;
+	ret = spi_w8r8(st->spi, cmd);
+	if (ret < 0)
+		return ret;
+	*val = ret;
+
+	return 0;
+};
+
+static int as3935_write(struct as3935_state *st,
+				unsigned int reg,
+				unsigned int val)
+{
+	u8 *buf = st->buf;
+
+	buf[0] = (AS3935_WRITE_DATA | AS3935_ADDRESS(reg)) >> 8;
+	buf[1] = val;
+
+	return spi_write(st->spi, buf, 2);
+};
+
+static ssize_t as3935_sensor_sensitivity_show(struct device *dev,
+					struct device_attribute *attr,
+					char *buf)
+{
+	struct as3935_state *st = iio_priv(dev_to_iio_dev(dev));
+	int val, ret;
+
+	ret = as3935_read(st, AS3935_AFE_GAIN, &val);
+	if (ret)
+		return ret;
+	val = (val & AS3935_AFE_MASK) >> 1;
+
+	return sprintf(buf, "%d\n", val);
+};
+
+static ssize_t as3935_sensor_sensitivity_store(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf, size_t len)
+{
+	struct as3935_state *st = iio_priv(dev_to_iio_dev(dev));
+	unsigned long val;
+	int ret;
+
+	ret = kstrtoul((const char *) buf, 10, &val);
+	if (ret)
+		return -EINVAL;
+
+	if (val > AS3935_AFE_GAIN_MAX)
+		return -EINVAL;
+
+	as3935_write(st, AS3935_AFE_GAIN, val << 1);
+
+	return len;
+};
+
+static IIO_DEVICE_ATTR(sensor_sensitivity, S_IRUGO | S_IWUSR,
+	as3935_sensor_sensitivity_show, as3935_sensor_sensitivity_store, 0);
+
+
+static struct attribute *as3935_attributes[] = {
+	&iio_dev_attr_sensor_sensitivity.dev_attr.attr,
+	NULL,
+};
+
+static struct attribute_group as3935_attribute_group = {
+	.attrs = as3935_attributes,
+};
+
+static int as3935_read_raw(struct iio_dev *indio_dev,
+			   struct iio_chan_spec const *chan,
+			   int *val,
+			   int *val2,
+			   long m)
+{
+	struct as3935_state *st = iio_priv(indio_dev);
+	int ret;
+
+
+	switch (m) {
+	case IIO_CHAN_INFO_PROCESSED:
+	case IIO_CHAN_INFO_RAW:
+		*val2 = 0;
+		ret = as3935_read(st, AS3935_DATA, val);
+		if (ret)
+			return ret;
+
+		if (m == IIO_CHAN_INFO_RAW)
+			return IIO_VAL_INT;
+
+		/* storm out of range */
+		if (*val == AS3935_DATA_MASK)
+			return -EINVAL;
+		*val *= 1000;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return IIO_VAL_INT;
+}
+
+static const struct iio_info as3935_info = {
+	.driver_module = THIS_MODULE,
+	.attrs = &as3935_attribute_group,
+	.read_raw = &as3935_read_raw,
+};
+
+static irqreturn_t as3935_trigger_handler(int irq, void *private)
+{
+	struct iio_poll_func *pf = private;
+	struct iio_dev *indio_dev = pf->indio_dev;
+	struct as3935_state *st = iio_priv(indio_dev);
+	int val, ret;
+
+	ret = as3935_read(st, AS3935_DATA, &val);
+	if (ret)
+		goto err_read;
+	val &= AS3935_DATA_MASK;
+	val *= 1000;
+
+	iio_push_to_buffers_with_timestamp(indio_dev, &val, pf->timestamp);
+err_read:
+	iio_trigger_notify_done(indio_dev->trig);
+
+	return IRQ_HANDLED;
+};
+
+static const struct iio_trigger_ops iio_interrupt_trigger_ops = {
+	.owner = THIS_MODULE,
+};
+
+static void as3935_event_work(struct work_struct *work)
+{
+	struct as3935_state *st;
+	int val;
+
+	st = container_of(work, struct as3935_state, work.work);
+
+	as3935_read(st, AS3935_INT, &val);
+	val &= AS3935_INT_MASK;
+
+	switch (val) {
+	case AS3935_EVENT_INT:
+		iio_trigger_poll(st->trig, iio_get_time_ns());
+		break;
+	case AS3935_NOISE_INT:
+		dev_warn(&st->spi->dev, "noise level is too high");
+		break;
+	}
+};
+
+static irqreturn_t as3935_interrupt_handler(int irq, void *private)
+{
+	struct iio_dev *indio_dev = private;
+	struct as3935_state *st = iio_priv(indio_dev);
+
+	/*
+	 * Delay work for >2 milliseconds after an interrupt to allow
+	 * estimated distance to recalculated.
+	 */
+
+	schedule_delayed_work(&st->work, msecs_to_jiffies(3));
+
+	return IRQ_HANDLED;
+}
+
+static void calibrate_as3935(struct as3935_state *st)
+{
+	mutex_lock(&st->lock);
+
+	/* mask disturber interrupt bit */
+	as3935_write(st, AS3935_INT, BIT(5));
+
+	as3935_write(st, AS3935_CALIBRATE, 0x96);
+	as3935_write(st, AS3935_TUNE_CAP,
+		BIT(5) | (st->tune_cap / TUNE_CAP_DIV));
+
+	mdelay(2);
+	as3935_write(st, AS3935_TUNE_CAP, (st->tune_cap / TUNE_CAP_DIV));
+
+	mutex_unlock(&st->lock);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int as3935_suspend(struct spi_device *spi, pm_message_t msg)
+{
+	struct iio_dev *indio_dev = spi_get_drvdata(spi);
+	struct as3935_state *st = iio_priv(indio_dev);
+	int val, ret;
+
+	mutex_lock(&st->lock);
+	ret = as3935_read(st, AS3935_AFE_GAIN, &val);
+	if (ret)
+		goto err_suspend;
+	val |= AS3935_AFE_PWR_BIT;
+
+	ret = as3935_write(st, AS3935_AFE_GAIN, val);
+
+err_suspend:
+	mutex_unlock(&st->lock);
+
+	return ret;
+}
+
+static int as3935_resume(struct spi_device *spi)
+{
+	struct iio_dev *indio_dev = spi_get_drvdata(spi);
+	struct as3935_state *st = iio_priv(indio_dev);
+	int val, ret;
+
+	mutex_lock(&st->lock);
+	ret = as3935_read(st, AS3935_AFE_GAIN, &val);
+	if (ret)
+		goto err_resume;
+	val &= ~AS3935_AFE_PWR_BIT;
+	ret = as3935_write(st, AS3935_AFE_GAIN, val);
+
+err_resume:
+	mutex_unlock(&st->lock);
+
+	return ret;
+}
+#else
+#define as3935_suspend	NULL
+#define as3935_resume	NULL
+#endif
+
+static int as3935_probe(struct spi_device *spi)
+{
+	struct iio_dev *indio_dev;
+	struct iio_trigger *trig;
+	struct as3935_state *st;
+	struct device_node *np = spi->dev.of_node;
+	int ret;
+
+	/* Be sure lightning event interrupt is specified */
+	if (!spi->irq) {
+		dev_err(&spi->dev, "unable to get event interrupt\n");
+		return -EINVAL;
+	}
+
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(st));
+	if (!indio_dev)
+		return -ENOMEM;
+
+	st = iio_priv(indio_dev);
+	st->spi = spi;
+	st->tune_cap = 0;
+
+	spi_set_drvdata(spi, indio_dev);
+	mutex_init(&st->lock);
+	INIT_DELAYED_WORK(&st->work, as3935_event_work);
+
+	ret = of_property_read_u32(np,
+			"ams,tuning-capacitor-pf", &st->tune_cap);
+	if (ret) {
+		st->tune_cap = 0;
+		dev_warn(&spi->dev,
+			"no tuning-capacitor-pf set, defaulting to %d",
+			st->tune_cap);
+	}
+
+	if (st->tune_cap > MAX_PF_CAP) {
+		dev_err(&spi->dev,
+			"wrong tuning-capacitor-pf setting of %d\n",
+			st->tune_cap);
+		return -EINVAL;
+	}
+
+	indio_dev->dev.parent = &spi->dev;
+	indio_dev->name = spi_get_device_id(spi)->name;
+	indio_dev->channels = as3935_channels;
+	indio_dev->num_channels = ARRAY_SIZE(as3935_channels);
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->info = &as3935_info;
+
+	trig = devm_iio_trigger_alloc(&spi->dev, "%s-dev%d",
+				      indio_dev->name, indio_dev->id);
+
+	if (!trig)
+		return -ENOMEM;
+
+	st->trig = trig;
+	trig->dev.parent = indio_dev->dev.parent;
+	iio_trigger_set_drvdata(trig, indio_dev);
+	trig->ops = &iio_interrupt_trigger_ops;
+
+	ret = iio_trigger_register(trig);
+	if (ret) {
+		dev_err(&spi->dev, "failed to register trigger\n");
+		return ret;
+	}
+
+	ret = iio_triggered_buffer_setup(indio_dev, NULL,
+		&as3935_trigger_handler, NULL);
+
+	if (ret) {
+		dev_err(&spi->dev, "cannot setup iio trigger\n");
+		goto unregister_trigger;
+	}
+
+	calibrate_as3935(st);
+
+	ret = devm_request_irq(&spi->dev, spi->irq,
+				&as3935_interrupt_handler,
+				IRQF_TRIGGER_RISING,
+				dev_name(&spi->dev),
+				indio_dev);
+
+	if (ret) {
+		dev_err(&spi->dev, "unable to request irq\n");
+		goto unregister_buffer;
+	}
+
+	ret = iio_device_register(indio_dev);
+	if (ret < 0) {
+		dev_err(&spi->dev, "unable to register device\n");
+		goto unregister_buffer;
+	}
+	return 0;
+
+unregister_buffer:
+	iio_triggered_buffer_cleanup(indio_dev);
+
+unregister_trigger:
+	iio_trigger_unregister(st->trig);
+
+	return ret;
+};
+
+static int as3935_remove(struct spi_device *spi)
+{
+	struct iio_dev *indio_dev = spi_get_drvdata(spi);
+	struct as3935_state *st = iio_priv(indio_dev);
+
+	iio_device_unregister(indio_dev);
+	iio_triggered_buffer_cleanup(indio_dev);
+	iio_trigger_unregister(st->trig);
+
+	return 0;
+};
+
+static const struct spi_device_id as3935_id[] = {
+	{"as3935", 0},
+	{},
+};
+MODULE_DEVICE_TABLE(spi, as3935_id);
+
+static struct spi_driver as3935_driver = {
+	.driver = {
+		.name	= "as3935",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= as3935_probe,
+	.remove		= as3935_remove,
+	.id_table	= as3935_id,
+	.suspend	= as3935_suspend,
+	.resume		= as3935_resume,
+};
+module_spi_driver(as3935_driver);
+
+MODULE_AUTHOR("Matt Ranostay <mranostay@gmail.com>");
+MODULE_DESCRIPTION("AS3935 lightning sensor");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("spi:as3935");
diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig
index 363329808a4fb88b723abbbdd31193f6c315741f..b87e382ad76898c5bdc6e01d34b8a41d7759196e 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
diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile
index 3e9fb143d25b4d3fe18ffc7c3abaf0133b51ef6f..afdcd1ff08ff1a775c9254d5d2aacaf4c162e263 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/ad7606.h b/drivers/staging/iio/adc/ad7606.h
index 93c7299e83539c2e38edb4d3b10e44867c2333dc..ec89d055cf585b8201f42cdf303cab13609eb3b5 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,7 +41,7 @@ struct ad7606_platform_data {
 };
 
 /**
- * struct ad7606_chip_info - chip specifc information
+ * struct ad7606_chip_info - chip specific information
  * @name:		identification string for chip
  * @int_vref_mv:	the internal reference voltage
  * @channels:		channel specification
diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c
index 2369cf28412ed682046e99c715b21a0b778faee5..158d770f961ac289824aaa1d6cfbfbf9314bd265 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 {
diff --git a/drivers/staging/iio/adc/ad799x.h b/drivers/staging/iio/adc/ad799x.h
deleted file mode 100644
index fc8c85298feb427b402d2c1c4678829e8ba126d7..0000000000000000000000000000000000000000
--- a/drivers/staging/iio/adc/ad799x.h
+++ /dev/null
@@ -1,121 +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_REG(x)			((x) * 3 + 0x4)
-#define AD7998_DATAHIGH_REG(x)			((x) * 3 + 0x5)
-#define AD7998_HYST_REG(x)			((x) * 3 + 0x6)
-
-#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;
-	struct regulator		*vref;
-	unsigned			id;
-	u16				config;
-
-	u8				*rx_buf;
-	unsigned int			transfer_size;
-};
-
-#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_ring.c b/drivers/staging/iio/adc/ad799x_ring.c
deleted file mode 100644
index 0ff6c03a483ec0bd72909c0eb49228baf2f555c7..0000000000000000000000000000000000000000
--- a/drivers/staging/iio/adc/ad799x_ring.c
+++ /dev/null
@@ -1,84 +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);
-	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;
-
-	iio_push_to_buffers_with_timestamp(indio_dev, st->rx_buf,
-			iio_get_time_ns());
-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/spear_adc.c b/drivers/staging/iio/adc/spear_adc.c
index 970d9edc73b6cc0d978a6a21a100de6c1a7a6994..c5492ba50751d3b9c415e15d4e43f5fed277ca58 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,100 +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);
+	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:
-		*val = info->vref_external;
-		*val2 = DATA_BITS;
+		*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[] = {
@@ -200,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,
 };
 
@@ -293,40 +261,40 @@ 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 = devm_iio_device_alloc(dev, 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");
 		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");
 		return -ENOMEM;
 	}
-	info->adc_base_spear3xx =
-		(struct adc_regs_spear3xx __iomem *)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 errout1;
 	}
 
-	ret = clk_prepare_enable(info->clk);
+	ret = clk_prepare_enable(st->clk);
 	if (ret) {
 		dev_err(dev, "failed enabling clock\n");
 		goto errout2;
@@ -339,14 +307,15 @@ static int spear_adc_probe(struct platform_device *pdev)
 		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 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 errout3;
@@ -356,28 +325,28 @@ static int spear_adc_probe(struct platform_device *pdev)
 	 * 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 errout3;
 
@@ -386,23 +355,23 @@ static int spear_adc_probe(struct platform_device *pdev)
 	return 0;
 
 errout3:
-	clk_disable_unprepare(info->clk);
+	clk_disable_unprepare(st->clk);
 errout2:
-	clk_put(info->clk);
+	clk_put(st->clk);
 errout1:
-	iounmap(info->adc_base_spear6xx);
+	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_unregister(indio_dev);
+	clk_disable_unprepare(st->clk);
+	clk_put(st->clk);
+	iounmap(st->adc_base_spear6xx);
 
 	return 0;
 }
@@ -419,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.c b/drivers/staging/iio/addac/adt7316.c
index 9f0ebb329008c40a809101f17206c5b0e8acf544..5f1770e6f6c3211edf5b3b063857fadb6fdcbcaa 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 {
diff --git a/drivers/staging/iio/cdc/ad7152.c b/drivers/staging/iio/cdc/ad7152.c
index f2c309d1eb5945a45137aab8882229a4b9ebab0c..87110d940e9a429d65d136abff4d93805ad8bdc7 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 {
diff --git a/drivers/staging/iio/cdc/ad7746.c b/drivers/staging/iio/cdc/ad7746.c
index cbb1588d591fdb698ffd22a58db3af0293e0be27..e6e9eaa9eab5477bf1f66ea64c01809e22527ea9 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 {
diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h
index 3c005eb3a0a4bab608479bd3ba7cd4d3dc65cd5f..96f51f0e00961c894c1a38b85f89873ea19d31af 100644
--- a/include/linux/iio/common/st_sensors.h
+++ b/include/linux/iio/common/st_sensors.h
@@ -269,6 +269,10 @@ int st_sensors_set_enable(struct iio_dev *indio_dev, bool enable);
 
 int st_sensors_set_axis_enable(struct iio_dev *indio_dev, u8 axis_enable);
 
+void st_sensors_power_enable(struct iio_dev *indio_dev);
+
+void st_sensors_power_disable(struct iio_dev *indio_dev);
+
 int st_sensors_set_odr(struct iio_dev *indio_dev, unsigned int odr);
 
 int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable);
diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h
index 2752b1fd12be3ea8b41c58f64b408d88f1afddaa..651f9a0e2765fa17a4896321478c15b9997f416e 100644
--- a/include/linux/iio/consumer.h
+++ b/include/linux/iio/consumer.h
@@ -122,6 +122,19 @@ struct iio_channel
 int iio_read_channel_raw(struct iio_channel *chan,
 			 int *val);
 
+/**
+ * iio_read_channel_average_raw() - read from a given channel
+ * @chan:		The channel being queried.
+ * @val:		Value read back.
+ *
+ * Note raw reads from iio channels are in adc counts and hence
+ * scale will need to be applied if standard units required.
+ *
+ * In opposit to the normal iio_read_channel_raw this function
+ * returns the average of multiple reads.
+ */
+int iio_read_channel_average_raw(struct iio_channel *chan, int *val);
+
 /**
  * iio_read_channel_processed() - read processed value from a given channel
  * @chan:		The channel being queried.