Browse Source

Merge tag 'iio-for-3.16a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next

Jonathan writes:

First round of IIO new driver, functionality and cleanups for the 3.16 cycle.

New device support
* AS3935 Lightning Sensor
* MCP3426/7/8 support added to the existing MCP3422 ADC driver
* AK8963 support in the AK8975 driver
* MPU6500 support in the MPU6050 driver (the functionality that is different
  is mostly not supported yet in either part).

Staging Graduations
* AD799x ADC

New functionality
* ACPI enumeration for the ak8975 driver

Cleanup / tweaks
* Use snprintf as a matter of good practice in a few additional places.
* Document *_mean_raw attributes.  These have been there a while, but were
  undocumented.
* Add an in kernel interface to get the mean values.
* Bug in the length of the event info mask that by coincidence wasn't yet
  actually causing any problems.
* itg3000 drop an unreachable return statement.
* spear_adc cleanups (heading for a staging graduation but a few more
  issues showed up in the review of these patches).
* Exynos ADC dependencies changed so it is only built when Exynos is present
  or COMPILE_TEST and OF are set.
* tsl2583 cleanups.
* Some cut and paste typos in the comments of various drivers still in staging.
* Couple of minor improvements to the ST sensor drivers.
Greg Kroah-Hartman 11 years ago
parent
commit
d5cef008e9
39 changed files with 1046 additions and 471 deletions
  1. 8 0
      Documentation/ABI/testing/sysfs-bus-iio
  2. 16 0
      Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935
  3. 28 0
      Documentation/devicetree/bindings/iio/proximity/as3935.txt
  4. 1 0
      Documentation/devicetree/bindings/vendor-prefixes.txt
  5. 1 0
      drivers/iio/Kconfig
  6. 1 0
      drivers/iio/Makefile
  7. 7 0
      drivers/iio/accel/st_accel_core.c
  8. 16 4
      drivers/iio/adc/Kconfig
  9. 1 0
      drivers/iio/adc/Makefile
  10. 141 4
      drivers/iio/adc/ad799x.c
  11. 28 5
      drivers/iio/adc/mcp3422.c
  12. 37 0
      drivers/iio/common/st_sensors/st_sensors_core.c
  13. 0 2
      drivers/iio/gyro/itg3200_core.c
  14. 7 0
      drivers/iio/gyro/st_gyro_core.c
  15. 2 0
      drivers/iio/imu/inv_mpu6050/Kconfig
  16. 1 0
      drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
  17. 1 0
      drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
  18. 4 2
      drivers/iio/industrialio-core.c
  19. 3 1
      drivers/iio/industrialio-event.c
  20. 18 0
      drivers/iio/inkern.c
  21. 2 1
      drivers/iio/magnetometer/Kconfig
  22. 64 6
      drivers/iio/magnetometer/ak8975.c
  23. 7 0
      drivers/iio/magnetometer/st_magn_core.c
  24. 5 37
      drivers/iio/pressure/st_pressure_core.c
  25. 19 0
      drivers/iio/proximity/Kconfig
  26. 6 0
      drivers/iio/proximity/Makefile
  27. 456 0
      drivers/iio/proximity/as3935.c
  28. 0 20
      drivers/staging/iio/adc/Kconfig
  29. 0 4
      drivers/staging/iio/adc/Makefile
  30. 2 2
      drivers/staging/iio/adc/ad7606.h
  31. 1 1
      drivers/staging/iio/adc/ad7816.c
  32. 0 121
      drivers/staging/iio/adc/ad799x.h
  33. 0 84
      drivers/staging/iio/adc/ad799x_ring.c
  34. 142 173
      drivers/staging/iio/adc/spear_adc.c
  35. 2 2
      drivers/staging/iio/addac/adt7316.c
  36. 1 1
      drivers/staging/iio/cdc/ad7152.c
  37. 1 1
      drivers/staging/iio/cdc/ad7746.c
  38. 4 0
      include/linux/iio/common/st_sensors.h
  39. 13 0
      include/linux/iio/consumer.h

+ 8 - 0
Documentation/ABI/testing/sysfs-bus-iio

@@ -210,6 +210,14 @@ Contact:	linux-iio@vger.kernel.org
 Description:
 Description:
 		Scaled humidity measurement in milli percent.
 		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_offset
 What:		/sys/bus/iio/devices/iio:deviceX/in_accel_x_offset
 What:		/sys/bus/iio/devices/iio:deviceX/in_accel_x_offset
 What:		/sys/bus/iio/devices/iio:deviceX/in_accel_y_offset
 What:		/sys/bus/iio/devices/iio:deviceX/in_accel_y_offset

+ 16 - 0
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

+ 28 - 0
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>;
+};

+ 1 - 0
Documentation/devicetree/bindings/vendor-prefixes.txt

@@ -13,6 +13,7 @@ allwinner	Allwinner Technology Co., Ltd.
 altr	Altera Corp.
 altr	Altera Corp.
 amcc	Applied Micro Circuits Corporation (APM, formally AMCC)
 amcc	Applied Micro Circuits Corporation (APM, formally AMCC)
 amd	Advanced Micro Devices (AMD), Inc.
 amd	Advanced Micro Devices (AMD), Inc.
+ams	AMS AG
 amstaos	AMS-Taos Inc.
 amstaos	AMS-Taos Inc.
 apm	Applied Micro Circuits Corporation (APM)
 apm	Applied Micro Circuits Corporation (APM)
 arm	ARM Ltd.
 arm	ARM Ltd.

+ 1 - 0
drivers/iio/Kconfig

@@ -74,6 +74,7 @@ if IIO_TRIGGER
    source "drivers/iio/trigger/Kconfig"
    source "drivers/iio/trigger/Kconfig"
 endif #IIO_TRIGGER
 endif #IIO_TRIGGER
 source "drivers/iio/pressure/Kconfig"
 source "drivers/iio/pressure/Kconfig"
+source "drivers/iio/proximity/Kconfig"
 source "drivers/iio/temperature/Kconfig"
 source "drivers/iio/temperature/Kconfig"
 
 
 endif # IIO
 endif # IIO

+ 1 - 0
drivers/iio/Makefile

@@ -24,5 +24,6 @@ obj-y += light/
 obj-y += magnetometer/
 obj-y += magnetometer/
 obj-y += orientation/
 obj-y += orientation/
 obj-y += pressure/
 obj-y += pressure/
+obj-y += proximity/
 obj-y += temperature/
 obj-y += temperature/
 obj-y += trigger/
 obj-y += trigger/

+ 7 - 0
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->modes = INDIO_DIRECT_MODE;
 	indio_dev->info = &accel_info;
 	indio_dev->info = &accel_info;
 
 
+	st_sensors_power_enable(indio_dev);
+
 	err = st_sensors_check_device_support(indio_dev,
 	err = st_sensors_check_device_support(indio_dev,
 				ARRAY_SIZE(st_accel_sensors), st_accel_sensors);
 				ARRAY_SIZE(st_accel_sensors), st_accel_sensors);
 	if (err < 0)
 	if (err < 0)
@@ -496,6 +498,9 @@ int st_accel_common_probe(struct iio_dev *indio_dev,
 	if (err)
 	if (err)
 		goto st_accel_device_register_error;
 		goto st_accel_device_register_error;
 
 
+	dev_info(&indio_dev->dev, "registered accelerometer %s\n",
+		 indio_dev->name);
+
 	return 0;
 	return 0;
 
 
 st_accel_device_register_error:
 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);
 	struct st_sensor_data *adata = iio_priv(indio_dev);
 
 
+	st_sensors_power_disable(indio_dev);
+
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
 	if (adata->get_irq_data_ready(indio_dev) > 0)
 	if (adata->get_irq_data_ready(indio_dev) > 0)
 		st_sensors_deallocate_trigger(indio_dev);
 		st_sensors_deallocate_trigger(indio_dev);

+ 16 - 4
drivers/iio/adc/Kconfig

@@ -96,6 +96,17 @@ config AD7923
 	  To compile this driver as a module, choose M here: the
 	  To compile this driver as a module, choose M here: the
 	  module will be called ad7923.
 	  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
 config AT91_ADC
 	tristate "Atmel AT91 ADC"
 	tristate "Atmel AT91 ADC"
 	depends on ARCH_AT91
 	depends on ARCH_AT91
@@ -107,7 +118,7 @@ config AT91_ADC
 
 
 config EXYNOS_ADC
 config EXYNOS_ADC
 	bool "Exynos ADC driver support"
 	bool "Exynos ADC driver support"
-	depends on OF
+	depends on ARCH_EXYNOS || (OF && COMPILE_TEST)
 	help
 	help
 	  Core support for the ADC block found in the Samsung EXYNOS series
 	  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
 	  of SoCs for drivers such as the touchscreen and hwmon to use to share
@@ -146,11 +157,12 @@ config MCP320X
 	  called mcp320x.
 	  called mcp320x.
 
 
 config MCP3422
 config MCP3422
-	tristate "Microchip Technology MCP3422/3/4 driver"
+	tristate "Microchip Technology MCP3422/3/4/6/7/8 driver"
 	depends on I2C
 	depends on I2C
 	help
 	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
 	  This driver can also be built as a module. If so, the module will be
 	  called mcp3422.
 	  called mcp3422.

+ 1 - 0
drivers/iio/adc/Makefile

@@ -11,6 +11,7 @@ obj-$(CONFIG_AD7476) += ad7476.o
 obj-$(CONFIG_AD7791) += ad7791.o
 obj-$(CONFIG_AD7791) += ad7791.o
 obj-$(CONFIG_AD7793) += ad7793.o
 obj-$(CONFIG_AD7793) += ad7793.o
 obj-$(CONFIG_AD7887) += ad7887.o
 obj-$(CONFIG_AD7887) += ad7887.o
+obj-$(CONFIG_AD799X) += ad799x.o
 obj-$(CONFIG_AT91_ADC) += at91_adc.o
 obj-$(CONFIG_AT91_ADC) += at91_adc.o
 obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
 obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
 obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
 obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o

+ 141 - 4
drivers/staging/iio/adc/ad799x_core.c → drivers/iio/adc/ad799x.c

@@ -37,8 +37,144 @@
 #include <linux/iio/sysfs.h>
 #include <linux/iio/sysfs.h>
 #include <linux/iio/events.h>
 #include <linux/iio/events.h>
 #include <linux/iio/buffer.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
  * 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->channels = st->chip_info->channel;
 	indio_dev->num_channels = st->chip_info->num_channels;
 	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)
 	if (ret)
 		goto error_disable_reg;
 		goto error_disable_reg;
 
 
@@ -601,7 +738,7 @@ static int ad799x_probe(struct i2c_client *client,
 	return 0;
 	return 0;
 
 
 error_cleanup_ring:
 error_cleanup_ring:
-	ad799x_ring_cleanup(indio_dev);
+	iio_triggered_buffer_cleanup(indio_dev);
 error_disable_reg:
 error_disable_reg:
 	if (!IS_ERR(st->vref))
 	if (!IS_ERR(st->vref))
 		regulator_disable(st->vref);
 		regulator_disable(st->vref);
@@ -618,7 +755,7 @@ static int ad799x_remove(struct i2c_client *client)
 
 
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
 
 
-	ad799x_ring_cleanup(indio_dev);
+	iio_triggered_buffer_cleanup(indio_dev);
 	if (!IS_ERR(st->vref))
 	if (!IS_ERR(st->vref))
 		regulator_disable(st->vref);
 		regulator_disable(st->vref);
 	if (!IS_ERR(st->reg))
 	if (!IS_ERR(st->reg))

+ 28 - 5
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
  * Copyright (C) 2013, Angelo Compagnucci
  * Author: Angelo Compagnucci <angelo.compagnucci@gmail.com>
  * Author: Angelo Compagnucci <angelo.compagnucci@gmail.com>
  *
  *
  * Datasheet: http://ww1.microchip.com/downloads/en/devicedoc/22088b.pdf
  * 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
  * This driver exports the value of analog input voltage to sysfs, the
  * voltage unit is nV.
  * voltage unit is nV.
@@ -96,6 +97,7 @@ static const int mcp3422_sign_extend[4] = {
 /* Client data (each client gets its own) */
 /* Client data (each client gets its own) */
 struct mcp3422 {
 struct mcp3422 {
 	struct i2c_client *i2c;
 	struct i2c_client *i2c;
+	u8 id;
 	u8 config;
 	u8 config;
 	u8 pga[4];
 	u8 pga[4];
 	struct mutex lock;
 	struct mutex lock;
@@ -238,6 +240,8 @@ static int mcp3422_write_raw(struct iio_dev *iio,
 			temp = MCP3422_SRATE_15;
 			temp = MCP3422_SRATE_15;
 			break;
 			break;
 		case 3:
 		case 3:
+			if (adc->id > 4)
+				return -EINVAL;
 			temp = MCP3422_SRATE_3;
 			temp = MCP3422_SRATE_3;
 			break;
 			break;
 		default:
 		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,
 static ssize_t mcp3422_show_scales(struct device *dev,
 		struct device_attribute *attr, char *buf)
 		struct device_attribute *attr, char *buf)
 {
 {
@@ -284,12 +299,13 @@ static ssize_t mcp3422_show_scales(struct device *dev,
 		mcp3422_scales[sample_rate][3]);
 		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,
 static IIO_DEVICE_ATTR(in_voltage_scale_available, S_IRUGO,
 		mcp3422_show_scales, NULL, 0);
 		mcp3422_show_scales, NULL, 0);
 
 
 static struct attribute *mcp3422_attributes[] = {
 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,
 	&iio_dev_attr_in_voltage_scale_available.dev_attr.attr,
 	NULL,
 	NULL,
 };
 };
@@ -335,6 +351,7 @@ static int mcp3422_probe(struct i2c_client *client,
 
 
 	adc = iio_priv(indio_dev);
 	adc = iio_priv(indio_dev);
 	adc->i2c = client;
 	adc->i2c = client;
+	adc->id = (u8)(id->driver_data);
 
 
 	mutex_init(&adc->lock);
 	mutex_init(&adc->lock);
 
 
@@ -343,13 +360,16 @@ static int mcp3422_probe(struct i2c_client *client,
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->info = &mcp3422_info;
 	indio_dev->info = &mcp3422_info;
 
 
-	switch ((unsigned int)(id->driver_data)) {
+	switch (adc->id) {
 	case 2:
 	case 2:
 	case 3:
 	case 3:
+	case 6:
+	case 7:
 		indio_dev->channels = mcp3422_channels;
 		indio_dev->channels = mcp3422_channels;
 		indio_dev->num_channels = ARRAY_SIZE(mcp3422_channels);
 		indio_dev->num_channels = ARRAY_SIZE(mcp3422_channels);
 		break;
 		break;
 	case 4:
 	case 4:
+	case 8:
 		indio_dev->channels = mcp3424_channels;
 		indio_dev->channels = mcp3424_channels;
 		indio_dev->num_channels = ARRAY_SIZE(mcp3424_channels);
 		indio_dev->num_channels = ARRAY_SIZE(mcp3424_channels);
 		break;
 		break;
@@ -375,6 +395,9 @@ static const struct i2c_device_id mcp3422_id[] = {
 	{ "mcp3422", 2 },
 	{ "mcp3422", 2 },
 	{ "mcp3423", 3 },
 	{ "mcp3423", 3 },
 	{ "mcp3424", 4 },
 	{ "mcp3424", 4 },
+	{ "mcp3426", 6 },
+	{ "mcp3427", 7 },
+	{ "mcp3428", 8 },
 	{ }
 	{ }
 };
 };
 MODULE_DEVICE_TABLE(i2c, mcp3422_id);
 MODULE_DEVICE_TABLE(i2c, mcp3422_id);
@@ -399,5 +422,5 @@ static struct i2c_driver mcp3422_driver = {
 module_i2c_driver(mcp3422_driver);
 module_i2c_driver(mcp3422_driver);
 
 
 MODULE_AUTHOR("Angelo Compagnucci <angelo.compagnucci@gmail.com>");
 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");
 MODULE_LICENSE("GPL v2");

+ 37 - 0
drivers/iio/common/st_sensors/st_sensors_core.c

@@ -13,6 +13,7 @@
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/iio.h>
+#include <linux/regulator/consumer.h>
 #include <asm/unaligned.h>
 #include <asm/unaligned.h>
 
 
 #include <linux/iio/common/st_sensors.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);
 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,
 static int st_sensors_set_drdy_int_pin(struct iio_dev *indio_dev,
 				       struct st_sensors_platform_data *pdata)
 				       struct st_sensors_platform_data *pdata)
 {
 {

+ 0 - 2
drivers/iio/gyro/itg3200_core.c

@@ -110,8 +110,6 @@ static int itg3200_read_raw(struct iio_dev *indio_dev,
 	default:
 	default:
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
-
-	return ret;
 }
 }
 
 
 static ssize_t itg3200_read_frequency(struct device *dev,
 static ssize_t itg3200_read_frequency(struct device *dev,

+ 7 - 0
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->modes = INDIO_DIRECT_MODE;
 	indio_dev->info = &gyro_info;
 	indio_dev->info = &gyro_info;
 
 
+	st_sensors_power_enable(indio_dev);
+
 	err = st_sensors_check_device_support(indio_dev,
 	err = st_sensors_check_device_support(indio_dev,
 				ARRAY_SIZE(st_gyro_sensors), st_gyro_sensors);
 				ARRAY_SIZE(st_gyro_sensors), st_gyro_sensors);
 	if (err < 0)
 	if (err < 0)
@@ -344,6 +346,9 @@ int st_gyro_common_probe(struct iio_dev *indio_dev,
 	if (err)
 	if (err)
 		goto st_gyro_device_register_error;
 		goto st_gyro_device_register_error;
 
 
+	dev_info(&indio_dev->dev, "registered gyroscope %s\n",
+		 indio_dev->name);
+
 	return 0;
 	return 0;
 
 
 st_gyro_device_register_error:
 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);
 	struct st_sensor_data *gdata = iio_priv(indio_dev);
 
 
+	st_sensors_power_disable(indio_dev);
+
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
 	if (gdata->get_irq_data_ready(indio_dev) > 0)
 	if (gdata->get_irq_data_ready(indio_dev) > 0)
 		st_sensors_deallocate_trigger(indio_dev);
 		st_sensors_deallocate_trigger(indio_dev);

+ 2 - 0
drivers/iio/imu/inv_mpu6050/Kconfig

@@ -9,6 +9,8 @@ config INV_MPU6050_IIO
 	select IIO_TRIGGERED_BUFFER
 	select IIO_TRIGGERED_BUFFER
 	help
 	help
 	  This driver supports the Invensense MPU6050 devices.
 	  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.
 	  It is a gyroscope/accelerometer combo device.
 	  This driver can be built as a module. The module will be called
 	  This driver can be built as a module. The module will be called
 	  inv-mpu6050.
 	  inv-mpu6050.

+ 1 - 0
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[] = {
 static const struct i2c_device_id inv_mpu_id[] = {
 	{"mpu6050", INV_MPU6050},
 	{"mpu6050", INV_MPU6050},
+	{"mpu6500", INV_MPU6500},
 	{}
 	{}
 };
 };
 
 

+ 1 - 0
drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h

@@ -59,6 +59,7 @@ struct inv_mpu6050_reg_map {
 /*device enum */
 /*device enum */
 enum inv_devices {
 enum inv_devices {
 	INV_MPU6050,
 	INV_MPU6050,
+	INV_MPU6500,
 	INV_NUM_PARTS
 	INV_NUM_PARTS
 };
 };
 
 

+ 4 - 2
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)
 	else if (i >= e->num_items)
 		return -EINVAL;
 		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);
 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;
 	int i, ret, attrcount = 0;
 
 
 	for_each_set_bit(i, infomask, sizeof(infomask)*8) {
 	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],
 		ret = __iio_add_chan_devattr(iio_chan_info_postfix[i],
 					     chan,
 					     chan,
 					     &iio_read_channel_info,
 					     &iio_read_channel_info,
@@ -820,7 +822,7 @@ static ssize_t iio_show_dev_name(struct device *dev,
 				 char *buf)
 				 char *buf)
 {
 {
 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 	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);
 static DEVICE_ATTR(name, S_IRUGO, iio_show_dev_name, NULL);

+ 3 - 1
drivers/iio/industrialio-event.c

@@ -321,7 +321,9 @@ static int iio_device_add_event(struct iio_dev *indio_dev,
 	char *postfix;
 	char *postfix;
 	int ret;
 	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",
 		postfix = kasprintf(GFP_KERNEL, "%s_%s_%s",
 				iio_ev_type_text[type], iio_ev_dir_text[dir],
 				iio_ev_type_text[type], iio_ev_dir_text[dir],
 				iio_ev_info_text[i]);
 				iio_ev_info_text[i]);

+ 18 - 0
drivers/iio/inkern.c

@@ -443,6 +443,24 @@ err_unlock:
 }
 }
 EXPORT_SYMBOL_GPL(iio_read_channel_raw);
 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,
 static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan,
 	int raw, int *processed, unsigned int scale)
 	int raw, int *processed, unsigned int scale)
 {
 {

+ 2 - 1
drivers/iio/magnetometer/Kconfig

@@ -11,7 +11,8 @@ config AK8975
 	depends on GPIOLIB
 	depends on GPIOLIB
 	help
 	help
 	  Say yes here to build support for Asahi Kasei AK8975 3-Axis
 	  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
 	  To compile this driver as a module, choose M here: the module
 	  will be called ak8975.
 	  will be called ak8975.

+ 64 - 6
drivers/iio/magnetometer/ak8975.c

@@ -31,6 +31,7 @@
 #include <linux/bitops.h>
 #include <linux/bitops.h>
 #include <linux/gpio.h>
 #include <linux/gpio.h>
 #include <linux/of_gpio.h>
 #include <linux/of_gpio.h>
+#include <linux/acpi.h>
 
 
 #include <linux/iio/iio.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
 #include <linux/iio/sysfs.h>
@@ -85,7 +86,14 @@
 #define AK8975_MAX_CONVERSION_TIMEOUT	500
 #define AK8975_MAX_CONVERSION_TIMEOUT	500
 #define AK8975_CONVERSION_DONE_POLL_TIME 10
 #define AK8975_CONVERSION_DONE_POLL_TIME 10
 #define AK8975_DATA_READY_TIMEOUT	((100*HZ)/1000)
 #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.
  * Per-instance context data for the device.
@@ -101,6 +109,7 @@ struct ak8975_data {
 	int			eoc_irq;
 	int			eoc_irq;
 	wait_queue_head_t	data_ready_queue;
 	wait_queue_head_t	data_ready_queue;
 	unsigned long		flags;
 	unsigned long		flags;
+	enum asahi_compass_chipset chipset;
 };
 };
 
 
 static const int ak8975_index_to_reg[] = {
 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
  * Since ASA doesn't change, we cache the resultant scale factor into the
  * device context in ak8975_setup().
  * 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;
 	return 0;
 }
 }
@@ -455,6 +476,27 @@ static const struct iio_info ak8975_info = {
 	.driver_module = THIS_MODULE,
 	.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,
 static int ak8975_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 			const struct i2c_device_id *id)
 {
 {
@@ -462,6 +504,7 @@ static int ak8975_probe(struct i2c_client *client,
 	struct iio_dev *indio_dev;
 	struct iio_dev *indio_dev;
 	int eoc_gpio;
 	int eoc_gpio;
 	int err;
 	int err;
+	char *name = NULL;
 
 
 	/* Grab and set up the supplied GPIO. */
 	/* Grab and set up the supplied GPIO. */
 	if (client->dev.platform_data)
 	if (client->dev.platform_data)
@@ -499,6 +542,19 @@ static int ak8975_probe(struct i2c_client *client,
 	data->eoc_gpio = eoc_gpio;
 	data->eoc_gpio = eoc_gpio;
 	data->eoc_irq = 0;
 	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. */
 	/* Perform some basic start-of-day setup of the device. */
 	err = ak8975_setup(client);
 	err = ak8975_setup(client);
 	if (err < 0) {
 	if (err < 0) {
@@ -515,7 +571,7 @@ static int ak8975_probe(struct i2c_client *client,
 	indio_dev->info = &ak8975_info;
 	indio_dev->info = &ak8975_info;
 	indio_dev->name = id->name;
 	indio_dev->name = id->name;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->modes = INDIO_DIRECT_MODE;
-
+	indio_dev->name = name;
 	err = iio_device_register(indio_dev);
 	err = iio_device_register(indio_dev);
 	if (err < 0)
 	if (err < 0)
 		goto exit_free_iio;
 		goto exit_free_iio;
@@ -552,7 +608,8 @@ static int ak8975_remove(struct i2c_client *client)
 }
 }
 
 
 static const struct i2c_device_id ak8975_id[] = {
 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 = {
 	.driver = {
 		.name	= "ak8975",
 		.name	= "ak8975",
 		.of_match_table = ak8975_of_match,
 		.of_match_table = ak8975_of_match,
+		.acpi_match_table = ACPI_PTR(ak_acpi_match),
 	},
 	},
 	.probe		= ak8975_probe,
 	.probe		= ak8975_probe,
 	.remove		= ak8975_remove,
 	.remove		= ak8975_remove,

+ 7 - 0
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->modes = INDIO_DIRECT_MODE;
 	indio_dev->info = &magn_info;
 	indio_dev->info = &magn_info;
 
 
+	st_sensors_power_enable(indio_dev);
+
 	err = st_sensors_check_device_support(indio_dev,
 	err = st_sensors_check_device_support(indio_dev,
 				ARRAY_SIZE(st_magn_sensors), st_magn_sensors);
 				ARRAY_SIZE(st_magn_sensors), st_magn_sensors);
 	if (err < 0)
 	if (err < 0)
@@ -387,6 +389,9 @@ int st_magn_common_probe(struct iio_dev *indio_dev,
 	if (err)
 	if (err)
 		goto st_magn_device_register_error;
 		goto st_magn_device_register_error;
 
 
+	dev_info(&indio_dev->dev, "registered magnetometer %s\n",
+		 indio_dev->name);
+
 	return 0;
 	return 0;
 
 
 st_magn_device_register_error:
 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);
 	struct st_sensor_data *mdata = iio_priv(indio_dev);
 
 
+	st_sensors_power_disable(indio_dev);
+
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
 	if (mdata->get_irq_data_ready(indio_dev) > 0)
 	if (mdata->get_irq_data_ready(indio_dev) > 0)
 		st_sensors_deallocate_trigger(indio_dev);
 		st_sensors_deallocate_trigger(indio_dev);

+ 5 - 37
drivers/iio/pressure/st_pressure_core.c

@@ -23,7 +23,6 @@
 #include <linux/iio/sysfs.h>
 #include <linux/iio/sysfs.h>
 #include <linux/iio/trigger.h>
 #include <linux/iio/trigger.h>
 #include <linux/iio/buffer.h>
 #include <linux/iio/buffer.h>
-#include <linux/regulator/consumer.h>
 #include <asm/unaligned.h>
 #include <asm/unaligned.h>
 
 
 #include <linux/iio/common/st_sensors.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
 #define ST_PRESS_TRIGGER_OPS NULL
 #endif
 #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,
 int st_press_common_probe(struct iio_dev *indio_dev,
 				struct st_sensors_platform_data *plat_data)
 				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->modes = INDIO_DIRECT_MODE;
 	indio_dev->info = &press_info;
 	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,
 	err = st_sensors_check_device_support(indio_dev,
 					      ARRAY_SIZE(st_press_sensors),
 					      ARRAY_SIZE(st_press_sensors),
@@ -474,6 +439,9 @@ int st_press_common_probe(struct iio_dev *indio_dev,
 	if (err)
 	if (err)
 		goto st_press_device_register_error;
 		goto st_press_device_register_error;
 
 
+	dev_info(&indio_dev->dev, "registered pressure sensor %s\n",
+		 indio_dev->name);
+
 	return err;
 	return err;
 
 
 st_press_device_register_error:
 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);
 	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);
 	iio_device_unregister(indio_dev);
 	if (pdata->get_irq_data_ready(indio_dev) > 0)
 	if (pdata->get_irq_data_ready(indio_dev) > 0)

+ 19 - 0
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

+ 6 - 0
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

+ 456 - 0
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");

+ 0 - 20
drivers/staging/iio/adc/Kconfig

@@ -37,26 +37,6 @@ config AD7606_IFACE_SPI
 	  Say yes here to include parallel interface support on the AD7606
 	  Say yes here to include parallel interface support on the AD7606
 	  ADC driver.
 	  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
 config AD7780
 	tristate "Analog Devices AD7780 and similar ADCs driver"
 	tristate "Analog Devices AD7780 and similar ADCs driver"
 	depends on SPI
 	depends on SPI

+ 0 - 4
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
 ad7606-$(CONFIG_AD7606_IFACE_SPI) += ad7606_spi.o
 obj-$(CONFIG_AD7606) += ad7606.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_AD7291) += ad7291.o
 obj-$(CONFIG_AD7780) += ad7780.o
 obj-$(CONFIG_AD7780) += ad7780.o
 obj-$(CONFIG_AD7816) += ad7816.o
 obj-$(CONFIG_AD7816) += ad7816.o

+ 2 - 2
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_os:		default oversampling value {0, 2, 4, 8, 16, 32, 64}
  * @default_range:	default range +/-{5000, 10000} mVolt
  * @default_range:	default range +/-{5000, 10000} mVolt
  * @gpio_convst:	number of gpio connected to the CONVST pin
  * @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
  * @name:		identification string for chip
  * @int_vref_mv:	the internal reference voltage
  * @int_vref_mv:	the internal reference voltage
  * @channels:		channel specification
  * @channels:		channel specification

+ 1 - 1
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 {
 struct ad7816_chip_info {

+ 0 - 121
drivers/staging/iio/adc/ad799x.h

@@ -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_ */

+ 0 - 84
drivers/staging/iio/adc/ad799x_ring.c

@@ -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);
-}

+ 142 - 173
drivers/staging/iio/adc/spear_adc.c

@@ -22,39 +22,36 @@
 #include <linux/iio/iio.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.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 */
 /* 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 {
 struct adc_regs_spear3xx {
 	u32 status;
 	u32 status;
 	u32 average;
 	u32 average;
 	u32 scan_rate;
 	u32 scan_rate;
 	u32 clk;	/* Not avail for 1340 & 1310 */
 	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 {
 struct chan_data {
@@ -66,14 +63,14 @@ struct adc_regs_spear6xx {
 	u32 status;
 	u32 status;
 	u32 pad[2];
 	u32 pad[2];
 	u32 clk;
 	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_lo;
 	u32 scan_rate_hi;
 	u32 scan_rate_hi;
 	struct chan_data average;
 	struct chan_data average;
 };
 };
 
 
-struct spear_adc_info {
+struct spear_adc_state {
 	struct device_node *np;
 	struct device_node *np;
 	struct adc_regs_spear3xx __iomem *adc_base_spear3xx;
 	struct adc_regs_spear3xx __iomem *adc_base_spear3xx;
 	struct adc_regs_spear6xx __iomem *adc_base_spear6xx;
 	struct adc_regs_spear6xx __iomem *adc_base_spear6xx;
@@ -91,100 +88,129 @@ struct spear_adc_info {
  * static inline functions, because of different register offsets
  * static inline functions, because of different register offsets
  * on different SoC variants (SPEAr300 vs SPEAr600 etc).
  * 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 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;
 	count = (apb_clk + val - 1) / val;
 	clk_low = count / 2;
 	clk_low = count / 2;
 	clk_high = count - clk_low;
 	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)
 			       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 {
 	} 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 {
 	} 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;
 	u32 status;
 
 
 	switch (mask) {
 	switch (mask) {
 	case IIO_CHAN_INFO_RAW:
 	case IIO_CHAN_INFO_RAW:
 		mutex_lock(&indio_dev->mlock);
 		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);
 		mutex_unlock(&indio_dev->mlock);
 
 
 		return IIO_VAL_INT;
 		return IIO_VAL_INT;
 
 
 	case IIO_CHAN_INFO_SCALE:
 	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;
 		return IIO_VAL_FRACTIONAL_LOG2;
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		*val = st->current_clk;
+		return IIO_VAL_INT;
 	}
 	}
 
 
 	return -EINVAL;
 	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) {				\
 #define SPEAR_ADC_CHAN(idx) {				\
 	.type = IIO_VOLTAGE,				\
 	.type = IIO_VOLTAGE,				\
 	.indexed = 1,					\
 	.indexed = 1,					\
 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),	\
 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),	\
 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
+	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),\
 	.channel = idx,					\
 	.channel = idx,					\
-	.scan_type = {					\
-		.sign = 'u',				\
-		.storagebits = 16,			\
-	},						\
 }
 }
 
 
 static const struct iio_chan_spec spear_adc_iio_channels[] = {
 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)
 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 */
 	/* 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;
 	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;
 	int i;
 
 
 	/* Reset ADC core */
 	/* 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++)
 	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;
 	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,
 	.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_node *np = pdev->dev.of_node;
 	struct device *dev = &pdev->dev;
 	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 ret = -ENODEV;
 	int irq;
 	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");
 		dev_err(dev, "failed allocating iio device\n");
 		return -ENOMEM;
 		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
 	 * SPEAr600 has a different register layout than other SPEAr SoC's
 	 * (e.g. SPEAr3xx). Let's provide two register base addresses
 	 * (e.g. SPEAr3xx). Let's provide two register base addresses
 	 * to support multi-arch kernels.
 	 * 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");
 		dev_err(dev, "failed mapping memory\n");
 		return -ENOMEM;
 		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");
 		dev_err(dev, "failed getting clock\n");
 		goto errout1;
 		goto errout1;
 	}
 	}
 
 
-	ret = clk_prepare_enable(info->clk);
+	ret = clk_prepare_enable(st->clk);
 	if (ret) {
 	if (ret) {
 		dev_err(dev, "failed enabling clock\n");
 		dev_err(dev, "failed enabling clock\n");
 		goto errout2;
 		goto errout2;
@@ -339,14 +307,15 @@ static int spear_adc_probe(struct platform_device *pdev)
 		goto errout3;
 		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) {
 	if (ret < 0) {
 		dev_err(dev, "failed requesting interrupt\n");
 		dev_err(dev, "failed requesting interrupt\n");
 		goto errout3;
 		goto errout3;
 	}
 	}
 
 
 	if (of_property_read_u32(np, "sampling-frequency",
 	if (of_property_read_u32(np, "sampling-frequency",
-				 &info->sampling_freq)) {
+				 &st->sampling_freq)) {
 		dev_err(dev, "sampling-frequency missing in DT\n");
 		dev_err(dev, "sampling-frequency missing in DT\n");
 		ret = -EINVAL;
 		ret = -EINVAL;
 		goto errout3;
 		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
 	 * Optional avg_samples defaults to 0, resulting in single data
 	 * conversion
 	 * 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
 	 * Optional vref_external defaults to 0, resulting in internal vref
 	 * selection
 	 * 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)
 	if (ret)
 		goto errout3;
 		goto errout3;
 
 
@@ -386,23 +355,23 @@ static int spear_adc_probe(struct platform_device *pdev)
 	return 0;
 	return 0;
 
 
 errout3:
 errout3:
-	clk_disable_unprepare(info->clk);
+	clk_disable_unprepare(st->clk);
 errout2:
 errout2:
-	clk_put(info->clk);
+	clk_put(st->clk);
 errout1:
 errout1:
-	iounmap(info->adc_base_spear6xx);
+	iounmap(st->adc_base_spear6xx);
 	return ret;
 	return ret;
 }
 }
 
 
 static int spear_adc_remove(struct platform_device *pdev)
 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;
 	return 0;
 }
 }
@@ -419,7 +388,7 @@ static struct platform_driver spear_adc_driver = {
 	.probe		= spear_adc_probe,
 	.probe		= spear_adc_probe,
 	.remove		= spear_adc_remove,
 	.remove		= spear_adc_remove,
 	.driver		= {
 	.driver		= {
-		.name	= MOD_NAME,
+		.name	= SPEAR_ADC_MOD_NAME,
 		.owner	= THIS_MODULE,
 		.owner	= THIS_MODULE,
 		.of_match_table = of_match_ptr(spear_adc_dt_ids),
 		.of_match_table = of_match_ptr(spear_adc_dt_ids),
 	},
 	},

+ 2 - 2
drivers/staging/iio/addac/adt7316.c

@@ -172,7 +172,7 @@
 #define ID_ADT75XX		0x10
 #define ID_ADT75XX		0x10
 
 
 /*
 /*
- * struct adt7316_chip_info - chip specifc information
+ * struct adt7316_chip_info - chip specific information
  */
  */
 
 
 struct adt7316_chip_info {
 struct adt7316_chip_info {
@@ -208,7 +208,7 @@ struct adt7316_chip_info {
 	(ADT7316_TEMP_INT_MASK)
 	(ADT7316_TEMP_INT_MASK)
 
 
 /*
 /*
- * struct adt7316_chip_info - chip specifc information
+ * struct adt7316_chip_info - chip specific information
  */
  */
 
 
 struct adt7316_limit_regs {
 struct adt7316_limit_regs {

+ 1 - 1
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 {
 struct ad7152_chip_info {

+ 1 - 1
drivers/staging/iio/cdc/ad7746.c

@@ -91,7 +91,7 @@
 #define AD7746_CAPDAC_DACP(x)		((x) & 0x7F)
 #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 {
 struct ad7746_chip_info {

+ 4 - 0
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);
 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_odr(struct iio_dev *indio_dev, unsigned int odr);
 
 
 int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable);
 int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable);

+ 13 - 0
include/linux/iio/consumer.h

@@ -122,6 +122,19 @@ struct iio_channel
 int iio_read_channel_raw(struct iio_channel *chan,
 int iio_read_channel_raw(struct iio_channel *chan,
 			 int *val);
 			 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
  * iio_read_channel_processed() - read processed value from a given channel
  * @chan:		The channel being queried.
  * @chan:		The channel being queried.