Browse Source

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

Jonathan writes:

Second set of new device support, features and cleanup for IIO in the 4.18 cycle

Usual mixture of new devices support and other stuff.  A couple of
staging graduations in here and some old driver drops.

New device support
* ad5686
  - Add support for AD5691R, AD5692R, AD5693 and AD5693R i2c DACs
  - Add support for AD5681R, AD5682R, AD5683 and AD5683R SPI DACs
* lmp91000
  - Add ID for LMP91002
* stm32-dfsdm
  - Add support for the stm32mp1 devices.

Drivers dropped
* ADE7753
  - No longer easily available, no users came forward and needs a lot
    of work to move out of staging.
* ADE7754
* ADE7758
* ADE7759

Staging graduations
- ad2s1200 - good cleanup from David Veenstra.
- tsl2772 (was tsl2x7x) - Brian's quest is at an end and
  staging/iio/light is no more!

Features
* tools
  - loop forever on a negative number of loops being specified.
* ltc 2632
  - add of_match_table
  - support an external reference regulator.
* mag3110
  - Support continuous mode when running fast as it increases the
    posssible sampling rate.
* ti-ads8688
  - Add trigger and buffer support to this ADC.

Cleanups / minor tweaks.
* tools
  - tidy up types in iio_generic_buffer.
* ad2s1200
  - Whitespace cleanup.
  - Drop pointless initializations.
  - Improve kernel docs.
  - Reorder to setup the SPI prior to device registration (race fix).
  - Change to modern gpiod framework.
  - Drop platform data and move to DT bindings. There are no in
    kernel users of the platform data. Any out of tree boards will
    need changes.
  - Add an explicit compatible table.
  - Provide _scale for angular velocity and angle channels.
  - Add David Veenstra to copyright notice as this cleanup was non
    trivial.
* ade8366
  - Avoid a race by ensuring channel init is before registration
    with the subsystem.
* afe
  - binding spelling fix.
* imx7d-adc
  - typo fix in Freescale
* inv_mpu6050
  - tidy up an ugly loop to take advantage of known entry condition.
  - add a comment explaining why the sensible sampling frequencies
    are more limited than might be immediately apparent (aliasing).
* mma8452
  - reduce the sleep time on data not ready when running at high
    frequency.
* stm32-dfsdm
  - add missing header.
* tsl2583
  - fix integration_time_availabe which was in microsecs rather the
    millisecs.
* tsl2x7x/tsl2772
  - Whitespace cleanup.
  - Change to direct returns where sensible.
  - Turn the chip off in the registration error path.
  - Use macro to reduce repition when setting up the device_info
    structures.
  - Change the _available attributes over to read_avail callback,
    and the range definitions that supports.
  - Fix some wrong period values.
  - Add some range checkign for _write_raw.
  - Rename the driver to tsl2772 to avoid wild card clash problems
    in future.
Greg Kroah-Hartman 7 years ago
parent
commit
5e667ac2dd
47 changed files with 1152 additions and 3939 deletions
  1. 5 2
      Documentation/devicetree/bindings/iio/adc/st,stm32-dfsdm-adc.txt
  2. 1 1
      Documentation/devicetree/bindings/iio/afe/current-sense-amplifier.txt
  3. 1 1
      Documentation/devicetree/bindings/iio/afe/current-sense-shunt.txt
  4. 14 0
      Documentation/devicetree/bindings/iio/dac/ltc2632.txt
  5. 6 3
      Documentation/devicetree/bindings/iio/potentiostat/lmp91000.txt
  6. 1 0
      drivers/iio/Kconfig
  7. 1 0
      drivers/iio/Makefile
  8. 23 1
      drivers/iio/accel/mma8452.c
  9. 1 1
      drivers/iio/adc/imx7d_adc.c
  10. 2 2
      drivers/iio/adc/stm32-dfsdm-adc.c
  11. 21 0
      drivers/iio/adc/stm32-dfsdm-core.c
  12. 45 3
      drivers/iio/adc/ti-ads8688.c
  13. 4 2
      drivers/iio/amplifiers/ad8366.c
  14. 34 8
      drivers/iio/dac/ad5686-spi.c
  15. 119 6
      drivers/iio/dac/ad5686.c
  16. 24 0
      drivers/iio/dac/ad5686.h
  17. 6 1
      drivers/iio/dac/ad5696-i2c.c
  18. 71 18
      drivers/iio/dac/ltc2632.c
  19. 8 1
      drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
  20. 2 2
      drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
  21. 8 0
      drivers/iio/light/Kconfig
  22. 1 0
      drivers/iio/light/Makefile
  23. 1 1
      drivers/iio/light/tsl2583.c
  24. 460 426
      drivers/iio/light/tsl2772.c
  25. 140 18
      drivers/iio/magnetometer/mag3110.c
  26. 2 0
      drivers/iio/potentiostat/lmp91000.c
  27. 17 0
      drivers/iio/resolver/Kconfig
  28. 5 0
      drivers/iio/resolver/Makefile
  29. 94 52
      drivers/iio/resolver/ad2s1200.c
  30. 0 1
      drivers/staging/iio/Kconfig
  31. 0 1
      drivers/staging/iio/Makefile
  32. 0 14
      drivers/staging/iio/light/Kconfig
  33. 0 5
      drivers/staging/iio/light/Makefile
  34. 0 42
      drivers/staging/iio/meter/Kconfig
  35. 0 8
      drivers/staging/iio/meter/Makefile
  36. 0 630
      drivers/staging/iio/meter/ade7753.c
  37. 0 664
      drivers/staging/iio/meter/ade7754.c
  38. 0 183
      drivers/staging/iio/meter/ade7758.h
  39. 0 955
      drivers/staging/iio/meter/ade7758_core.c
  40. 0 177
      drivers/staging/iio/meter/ade7758_ring.c
  41. 0 108
      drivers/staging/iio/meter/ade7758_trigger.c
  42. 0 558
      drivers/staging/iio/meter/ade7759.c
  43. 0 12
      drivers/staging/iio/resolver/Kconfig
  44. 0 1
      drivers/staging/iio/resolver/Makefile
  45. 2 0
      include/linux/iio/adc/stm32-dfsdm-adc.h
  46. 25 26
      include/linux/platform_data/tsl2772.h
  47. 8 5
      tools/iio/iio_generic_buffer.c

+ 5 - 2
Documentation/devicetree/bindings/iio/adc/st,stm32-dfsdm-adc.txt

@@ -8,14 +8,16 @@ It is mainly targeted for:
 - PDM microphones (audio digital microphone)
 
 It features up to 8 serial digital interfaces (SPI or Manchester) and
-up to 4 filters on stm32h7.
+up to 4 filters on stm32h7 or 6 filters on stm32mp1.
 
 Each child node match with a filter instance.
 
 Contents of a STM32 DFSDM root node:
 ------------------------------------
 Required properties:
-- compatible: Should be "st,stm32h7-dfsdm".
+- compatible: Should be one of:
+  "st,stm32h7-dfsdm"
+  "st,stm32mp1-dfsdm"
 - reg: Offset and length of the DFSDM block register set.
 - clocks: IP and serial interfaces clocking. Should be set according
 		to rcc clock ID and "clock-names".
@@ -45,6 +47,7 @@ Required properties:
 	"st,stm32-dfsdm-adc" for sigma delta ADCs
 	"st,stm32-dfsdm-dmic" for audio digital microphone.
 - reg: Specifies the DFSDM filter instance used.
+	Valid values are from 0 to 3 on stm32h7, 0 to 5 on stm32mp1.
 - interrupts: IRQ lines connected to each DFSDM filter instance.
 - st,adc-channels:	List of single-ended channels muxed for this ADC.
 			valid values:

+ 1 - 1
Documentation/devicetree/bindings/iio/afe/current-sense-amplifier.txt

@@ -2,7 +2,7 @@ Current Sense Amplifier
 =======================
 
 When an io-channel measures the output voltage from a current sense
-amplifier, the interesting mesaurement is almost always the current
+amplifier, the interesting measurement is almost always the current
 through the sense resistor, not the voltage output. This binding
 describes such a current sense circuit.
 

+ 1 - 1
Documentation/devicetree/bindings/iio/afe/current-sense-shunt.txt

@@ -2,7 +2,7 @@ Current Sense Shunt
 ===================
 
 When an io-channel measures the voltage over a current sense shunt,
-the interesting mesaurement is almost always the current through the
+the interesting measurement is almost always the current through the
 shunt, not the voltage over it. This binding describes such a current
 sense circuit.
 

+ 14 - 0
Documentation/devicetree/bindings/iio/dac/ltc2632.txt

@@ -12,12 +12,26 @@ Required properties:
 Property rules described in Documentation/devicetree/bindings/spi/spi-bus.txt
 apply. In particular, "reg" and "spi-max-frequency" properties must be given.
 
+Optional properties:
+	- vref-supply: Phandle to the external reference voltage supply. This should
+	  only be set if there is an external reference voltage connected to the VREF
+	  pin. If the property is not set the internal reference is used.
+
 Example:
 
+	vref: regulator-vref {
+		compatible = "regulator-fixed";
+		regulator-name = "vref-ltc2632";
+		regulator-min-microvolt = <1250000>;
+		regulator-max-microvolt = <1250000>;
+		regulator-always-on;
+	};
+
 	spi_master {
 		dac: ltc2632@0 {
 			compatible = "lltc,ltc2632-l12";
 			reg = <0>; /* CS0 */
 			spi-max-frequency = <1000000>;
+			vref-supply = <&vref>; /* optional */
 		};
 	};

+ 6 - 3
Documentation/devicetree/bindings/iio/potentiostat/lmp91000.txt

@@ -1,10 +1,13 @@
-* Texas Instruments LMP91000 potentiostat
+* Texas Instruments LMP91000 series of potentiostats
 
-http://www.ti.com/lit/ds/symlink/lmp91000.pdf
+LMP91000: http://www.ti.com/lit/ds/symlink/lmp91000.pdf
+LMP91002: http://www.ti.com/lit/ds/symlink/lmp91002.pdf
 
 Required properties:
 
-  - compatible: should be "ti,lmp91000"
+  - compatible: should be one of the following:
+                 "ti,lmp91000"
+                 "ti,lmp91002"
   - reg: the I2C address of the device
   - io-channels: the phandle of the iio provider
 

+ 1 - 0
drivers/iio/Kconfig

@@ -93,6 +93,7 @@ source "drivers/iio/potentiometer/Kconfig"
 source "drivers/iio/potentiostat/Kconfig"
 source "drivers/iio/pressure/Kconfig"
 source "drivers/iio/proximity/Kconfig"
+source "drivers/iio/resolver/Kconfig"
 source "drivers/iio/temperature/Kconfig"
 
 endif # IIO

+ 1 - 0
drivers/iio/Makefile

@@ -36,5 +36,6 @@ obj-y += potentiometer/
 obj-y += potentiostat/
 obj-y += pressure/
 obj-y += proximity/
+obj-y += resolver/
 obj-y += temperature/
 obj-y += trigger/

+ 23 - 1
drivers/iio/accel/mma8452.c

@@ -106,6 +106,7 @@ struct mma8452_data {
 	u8 ctrl_reg1;
 	u8 data_cfg;
 	const struct mma_chip_info *chip_info;
+	int sleep_val;
 };
 
  /**
@@ -193,7 +194,11 @@ static int mma8452_drdy(struct mma8452_data *data)
 		if ((ret & MMA8452_STATUS_DRDY) == MMA8452_STATUS_DRDY)
 			return 0;
 
-		msleep(20);
+		if (data->sleep_val <= 20)
+			usleep_range(data->sleep_val * 250,
+				     data->sleep_val * 500);
+		else
+			msleep(20);
 	}
 
 	dev_err(&data->client->dev, "data not ready\n");
@@ -544,6 +549,18 @@ static int mma8452_read_raw(struct iio_dev *indio_dev,
 	return -EINVAL;
 }
 
+static int mma8452_calculate_sleep(struct mma8452_data *data)
+{
+	int ret, i = mma8452_get_odr_index(data);
+
+	if (mma8452_samp_freq[i][0] > 0)
+		ret = 1000 / mma8452_samp_freq[i][0];
+	else
+		ret = 1000;
+
+	return ret == 0 ? 1 : ret;
+}
+
 static int mma8452_standby(struct mma8452_data *data)
 {
 	return i2c_smbus_write_byte_data(data->client, MMA8452_CTRL_REG1,
@@ -700,6 +717,8 @@ static int mma8452_write_raw(struct iio_dev *indio_dev,
 		data->ctrl_reg1 &= ~MMA8452_CTRL_DR_MASK;
 		data->ctrl_reg1 |= i << MMA8452_CTRL_DR_SHIFT;
 
+		data->sleep_val = mma8452_calculate_sleep(data);
+
 		ret = mma8452_change_config(data, MMA8452_CTRL_REG1,
 					    data->ctrl_reg1);
 		break;
@@ -1593,6 +1612,9 @@ static int mma8452_probe(struct i2c_client *client,
 
 	data->ctrl_reg1 = MMA8452_CTRL_ACTIVE |
 			  (MMA8452_CTRL_DR_DEFAULT << MMA8452_CTRL_DR_SHIFT);
+
+	data->sleep_val = mma8452_calculate_sleep(data);
+
 	ret = i2c_smbus_write_byte_data(client, MMA8452_CTRL_REG1,
 					data->ctrl_reg1);
 	if (ret < 0)

+ 1 - 1
drivers/iio/adc/imx7d_adc.c

@@ -604,5 +604,5 @@ static struct platform_driver imx7d_adc_driver = {
 module_platform_driver(imx7d_adc_driver);
 
 MODULE_AUTHOR("Haibo Chen <haibo.chen@freescale.com>");
-MODULE_DESCRIPTION("Freeacale IMX7D ADC driver");
+MODULE_DESCRIPTION("Freescale IMX7D ADC driver");
 MODULE_LICENSE("GPL v2");

+ 2 - 2
drivers/iio/adc/stm32-dfsdm-adc.c

@@ -8,11 +8,11 @@
 
 #include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
-#include <linux/interrupt.h>
+#include <linux/iio/adc/stm32-dfsdm-adc.h>
 #include <linux/iio/buffer.h>
 #include <linux/iio/hw-consumer.h>
-#include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
+#include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>

+ 21 - 0
drivers/iio/adc/stm32-dfsdm-core.c

@@ -25,6 +25,8 @@ struct stm32_dfsdm_dev_data {
 
 #define STM32H7_DFSDM_NUM_FILTERS	4
 #define STM32H7_DFSDM_NUM_CHANNELS	8
+#define STM32MP1_DFSDM_NUM_FILTERS	6
+#define STM32MP1_DFSDM_NUM_CHANNELS	8
 
 static bool stm32_dfsdm_volatile_reg(struct device *dev, unsigned int reg)
 {
@@ -61,6 +63,21 @@ static const struct stm32_dfsdm_dev_data stm32h7_dfsdm_data = {
 	.regmap_cfg = &stm32h7_dfsdm_regmap_cfg,
 };
 
+static const struct regmap_config stm32mp1_dfsdm_regmap_cfg = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = sizeof(u32),
+	.max_register = 0x7fc,
+	.volatile_reg = stm32_dfsdm_volatile_reg,
+	.fast_io = true,
+};
+
+static const struct stm32_dfsdm_dev_data stm32mp1_dfsdm_data = {
+	.num_filters = STM32MP1_DFSDM_NUM_FILTERS,
+	.num_channels = STM32MP1_DFSDM_NUM_CHANNELS,
+	.regmap_cfg = &stm32mp1_dfsdm_regmap_cfg,
+};
+
 struct dfsdm_priv {
 	struct platform_device *pdev; /* platform device */
 
@@ -248,6 +265,10 @@ static const struct of_device_id stm32_dfsdm_of_match[] = {
 		.compatible = "st,stm32h7-dfsdm",
 		.data = &stm32h7_dfsdm_data,
 	},
+	{
+		.compatible = "st,stm32mp1-dfsdm",
+		.data = &stm32mp1_dfsdm_data,
+	},
 	{}
 };
 MODULE_DEVICE_TABLE(of, stm32_dfsdm_of_match);

+ 45 - 3
drivers/iio/adc/ti-ads8688.c

@@ -17,6 +17,9 @@
 #include <linux/of.h>
 
 #include <linux/iio/iio.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
 #include <linux/iio/sysfs.h>
 
 #define ADS8688_CMD_REG(x)		(x << 8)
@@ -155,6 +158,13 @@ static const struct attribute_group ads8688_attribute_group = {
 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW)		\
 			      | BIT(IIO_CHAN_INFO_SCALE)	\
 			      | BIT(IIO_CHAN_INFO_OFFSET),	\
+	.scan_index = index,					\
+	.scan_type = {						\
+		.sign = 'u',					\
+		.realbits = 16,					\
+		.storagebits = 16,				\
+		.endianness = IIO_BE,				\
+	},							\
 }
 
 static const struct iio_chan_spec ads8684_channels[] = {
@@ -371,6 +381,28 @@ static const struct iio_info ads8688_info = {
 	.attrs = &ads8688_attribute_group,
 };
 
+static irqreturn_t ads8688_trigger_handler(int irq, void *p)
+{
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->indio_dev;
+	u16 buffer[8];
+	int i, j = 0;
+
+	for (i = 0; i < indio_dev->masklength; i++) {
+		if (!test_bit(i, indio_dev->active_scan_mask))
+			continue;
+		buffer[j] = ads8688_read(indio_dev, i);
+		j++;
+	}
+
+	iio_push_to_buffers_with_timestamp(indio_dev, buffer,
+			pf->timestamp);
+
+	iio_trigger_notify_done(indio_dev->trig);
+
+	return IRQ_HANDLED;
+}
+
 static const struct ads8688_chip_info ads8688_chip_info_tbl[] = {
 	[ID_ADS8684] = {
 		.channels = ads8684_channels,
@@ -402,7 +434,7 @@ static int ads8688_probe(struct spi_device *spi)
 
 		ret = regulator_get_voltage(st->reg);
 		if (ret < 0)
-			goto error_out;
+			goto err_regulator_disable;
 
 		st->vref_mv = ret / 1000;
 	} else {
@@ -430,13 +462,22 @@ static int ads8688_probe(struct spi_device *spi)
 
 	mutex_init(&st->lock);
 
+	ret = iio_triggered_buffer_setup(indio_dev, NULL, ads8688_trigger_handler, NULL);
+	if (ret < 0) {
+		dev_err(&spi->dev, "iio triggered buffer setup failed\n");
+		goto err_regulator_disable;
+	}
+
 	ret = iio_device_register(indio_dev);
 	if (ret)
-		goto error_out;
+		goto err_buffer_cleanup;
 
 	return 0;
 
-error_out:
+err_buffer_cleanup:
+	iio_triggered_buffer_cleanup(indio_dev);
+
+err_regulator_disable:
 	if (!IS_ERR(st->reg))
 		regulator_disable(st->reg);
 
@@ -449,6 +490,7 @@ static int ads8688_remove(struct spi_device *spi)
 	struct ads8688_state *st = iio_priv(indio_dev);
 
 	iio_device_unregister(indio_dev);
+	iio_triggered_buffer_cleanup(indio_dev);
 
 	if (!IS_ERR(st->reg))
 		regulator_disable(st->reg);

+ 4 - 2
drivers/iio/amplifiers/ad8366.c

@@ -161,12 +161,14 @@ static int ad8366_probe(struct spi_device *spi)
 	indio_dev->channels = ad8366_channels;
 	indio_dev->num_channels = ARRAY_SIZE(ad8366_channels);
 
+	ret = ad8366_write(indio_dev, 0 , 0);
+	if (ret < 0)
+		goto error_disable_reg;
+
 	ret = iio_device_register(indio_dev);
 	if (ret)
 		goto error_disable_reg;
 
-	ad8366_write(indio_dev, 0, 0);
-
 	return 0;
 
 error_disable_reg:

+ 34 - 8
drivers/iio/dac/ad5686-spi.c

@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * AD5672R, AD5676, AD5676R, AD5684, AD5684R, AD5684R, AD5685R, AD5686, AD5686R
+ * AD5672R, AD5676, AD5676R, AD5681R, AD5682R, AD5683, AD5683R,
+ * AD5684, AD5684R, AD5685R, AD5686, AD5686R
  * Digital to analog converters driver
  *
  * Copyright 2018 Analog Devices Inc.
@@ -15,12 +16,27 @@ static int ad5686_spi_write(struct ad5686_state *st,
 			    u8 cmd, u8 addr, u16 val)
 {
 	struct spi_device *spi = to_spi_device(st->dev);
-
-	st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) |
-				      AD5686_ADDR(addr) |
-				      val);
-
-	return spi_write(spi, &st->data[0].d8[1], 3);
+	u8 tx_len, *buf;
+
+	switch (st->chip_info->regmap_type) {
+	case AD5683_REGMAP:
+		st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) |
+					      AD5683_DATA(val));
+		buf = &st->data[0].d8[1];
+		tx_len = 3;
+		break;
+	case AD5686_REGMAP:
+		st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) |
+					      AD5686_ADDR(addr) |
+					      val);
+		buf = &st->data[0].d8[1];
+		tx_len = 3;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return spi_write(spi, buf, tx_len);
 }
 
 static int ad5686_spi_read(struct ad5686_state *st, u8 addr)
@@ -37,9 +53,15 @@ static int ad5686_spi_read(struct ad5686_state *st, u8 addr)
 		},
 	};
 	struct spi_device *spi = to_spi_device(st->dev);
+	u8 cmd = 0;
 	int ret;
 
-	st->data[0].d32 = cpu_to_be32(AD5686_CMD(AD5686_CMD_READBACK_ENABLE) |
+	if (st->chip_info->regmap_type == AD5686_REGMAP)
+		cmd = AD5686_CMD_READBACK_ENABLE;
+	else if (st->chip_info->regmap_type == AD5683_REGMAP)
+		cmd = AD5686_CMD_READBACK_ENABLE_V2;
+
+	st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) |
 				      AD5686_ADDR(addr));
 	st->data[1].d32 = cpu_to_be32(AD5686_CMD(AD5686_CMD_NOOP));
 
@@ -67,6 +89,10 @@ static const struct spi_device_id ad5686_spi_id[] = {
 	{"ad5672r", ID_AD5672R},
 	{"ad5676", ID_AD5676},
 	{"ad5676r", ID_AD5676R},
+	{"ad5681r", ID_AD5681R},
+	{"ad5682r", ID_AD5682R},
+	{"ad5683", ID_AD5683},
+	{"ad5683r", ID_AD5683R},
 	{"ad5684", ID_AD5684},
 	{"ad5684r", ID_AD5684R},
 	{"ad5685", ID_AD5685R}, /* Does not exist */

+ 119 - 6
drivers/iio/dac/ad5686.c

@@ -70,6 +70,8 @@ static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev,
 	bool readin;
 	int ret;
 	struct ad5686_state *st = iio_priv(indio_dev);
+	unsigned int val, ref_bit_msk;
+	u8 shift;
 
 	ret = strtobool(buf, &readin);
 	if (ret)
@@ -80,9 +82,28 @@ static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev,
 	else
 		st->pwr_down_mask &= ~(0x3 << (chan->channel * 2));
 
-	ret = st->write(st, AD5686_CMD_POWERDOWN_DAC, 0,
-			st->pwr_down_mask & st->pwr_down_mode);
+	switch (st->chip_info->regmap_type) {
+	case AD5683_REGMAP:
+		shift = 13;
+		ref_bit_msk = AD5683_REF_BIT_MSK;
+		break;
+	case AD5686_REGMAP:
+		shift = 0;
+		ref_bit_msk = 0;
+		break;
+	case AD5693_REGMAP:
+		shift = 13;
+		ref_bit_msk = AD5693_REF_BIT_MSK;
+		break;
+	default:
+		return -EINVAL;
+	}
 
+	val = ((st->pwr_down_mask & st->pwr_down_mode) << shift);
+	if (!st->use_internal_vref)
+		val |= ref_bit_msk;
+
+	ret = st->write(st, AD5686_CMD_POWERDOWN_DAC, 0, val);
 
 	return ret ? ret : len;
 }
@@ -175,6 +196,11 @@ static const struct iio_chan_spec_ext_info ad5686_ext_info[] = {
 		.ext_info = ad5686_ext_info,			\
 }
 
+#define DECLARE_AD5693_CHANNELS(name, bits, _shift)		\
+static struct iio_chan_spec name[] = {				\
+		AD5868_CHANNEL(0, 0, bits, _shift),		\
+}
+
 #define DECLARE_AD5686_CHANNELS(name, bits, _shift)		\
 static struct iio_chan_spec name[] = {				\
 		AD5868_CHANNEL(0, 1, bits, _shift),		\
@@ -200,72 +226,135 @@ DECLARE_AD5676_CHANNELS(ad5676_channels, 16, 0);
 DECLARE_AD5686_CHANNELS(ad5684_channels, 12, 4);
 DECLARE_AD5686_CHANNELS(ad5685r_channels, 14, 2);
 DECLARE_AD5686_CHANNELS(ad5686_channels, 16, 0);
+DECLARE_AD5693_CHANNELS(ad5693_channels, 16, 0);
+DECLARE_AD5693_CHANNELS(ad5692r_channels, 14, 2);
+DECLARE_AD5693_CHANNELS(ad5691r_channels, 12, 4);
 
 static const struct ad5686_chip_info ad5686_chip_info_tbl[] = {
 	[ID_AD5671R] = {
 		.channels = ad5672_channels,
 		.int_vref_mv = 2500,
 		.num_channels = 8,
+		.regmap_type = AD5686_REGMAP,
 	},
 	[ID_AD5672R] = {
 		.channels = ad5672_channels,
 		.int_vref_mv = 2500,
 		.num_channels = 8,
+		.regmap_type = AD5686_REGMAP,
 	},
 	[ID_AD5675R] = {
 		.channels = ad5676_channels,
 		.int_vref_mv = 2500,
 		.num_channels = 8,
+		.regmap_type = AD5686_REGMAP,
 	},
 	[ID_AD5676] = {
 		.channels = ad5676_channels,
 		.num_channels = 8,
+		.regmap_type = AD5686_REGMAP,
 	},
 	[ID_AD5676R] = {
 		.channels = ad5676_channels,
 		.int_vref_mv = 2500,
 		.num_channels = 8,
+		.regmap_type = AD5686_REGMAP,
+	},
+	[ID_AD5681R] = {
+		.channels = ad5691r_channels,
+		.int_vref_mv = 2500,
+		.num_channels = 1,
+		.regmap_type = AD5683_REGMAP,
+	},
+	[ID_AD5682R] = {
+		.channels = ad5692r_channels,
+		.int_vref_mv = 2500,
+		.num_channels = 1,
+		.regmap_type = AD5683_REGMAP,
+	},
+	[ID_AD5683] = {
+		.channels = ad5693_channels,
+		.num_channels = 1,
+		.regmap_type = AD5683_REGMAP,
+	},
+	[ID_AD5683R] = {
+		.channels = ad5693_channels,
+		.int_vref_mv = 2500,
+		.num_channels = 1,
+		.regmap_type = AD5683_REGMAP,
 	},
 	[ID_AD5684] = {
 		.channels = ad5684_channels,
 		.num_channels = 4,
+		.regmap_type = AD5686_REGMAP,
 	},
 	[ID_AD5684R] = {
 		.channels = ad5684_channels,
 		.int_vref_mv = 2500,
 		.num_channels = 4,
+		.regmap_type = AD5686_REGMAP,
 	},
 	[ID_AD5685R] = {
 		.channels = ad5685r_channels,
 		.int_vref_mv = 2500,
 		.num_channels = 4,
+		.regmap_type = AD5686_REGMAP,
 	},
 	[ID_AD5686] = {
 		.channels = ad5686_channels,
 		.num_channels = 4,
+		.regmap_type = AD5686_REGMAP,
 	},
 	[ID_AD5686R] = {
 		.channels = ad5686_channels,
 		.int_vref_mv = 2500,
 		.num_channels = 4,
+		.regmap_type = AD5686_REGMAP,
+	},
+	[ID_AD5691R] = {
+		.channels = ad5691r_channels,
+		.int_vref_mv = 2500,
+		.num_channels = 1,
+		.regmap_type = AD5693_REGMAP,
+	},
+	[ID_AD5692R] = {
+		.channels = ad5692r_channels,
+		.int_vref_mv = 2500,
+		.num_channels = 1,
+		.regmap_type = AD5693_REGMAP,
+	},
+	[ID_AD5693] = {
+		.channels = ad5693_channels,
+		.num_channels = 1,
+		.regmap_type = AD5693_REGMAP,
+	},
+	[ID_AD5693R] = {
+		.channels = ad5693_channels,
+		.int_vref_mv = 2500,
+		.num_channels = 1,
+		.regmap_type = AD5693_REGMAP,
 	},
 	[ID_AD5694] = {
 		.channels = ad5684_channels,
 		.num_channels = 4,
+		.regmap_type = AD5686_REGMAP,
 	},
 	[ID_AD5694R] = {
 		.channels = ad5684_channels,
 		.int_vref_mv = 2500,
 		.num_channels = 4,
+		.regmap_type = AD5686_REGMAP,
 	},
 	[ID_AD5696] = {
 		.channels = ad5686_channels,
 		.num_channels = 4,
+		.regmap_type = AD5686_REGMAP,
 	},
 	[ID_AD5696R] = {
 		.channels = ad5686_channels,
 		.int_vref_mv = 2500,
 		.num_channels = 4,
+		.regmap_type = AD5686_REGMAP,
 	},
 };
 
@@ -276,7 +365,9 @@ int ad5686_probe(struct device *dev,
 {
 	struct ad5686_state *st;
 	struct iio_dev *indio_dev;
-	int ret, voltage_uv = 0;
+	unsigned int val, ref_bit_msk;
+	u8 cmd;
+	int ret, i, voltage_uv = 0;
 
 	indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
 	if (indio_dev == NULL)
@@ -310,7 +401,8 @@ int ad5686_probe(struct device *dev,
 		st->vref_mv = st->chip_info->int_vref_mv;
 
 	/* Set all the power down mode for all channels to 1K pulldown */
-	st->pwr_down_mode = 0x55;
+	for (i = 0; i < st->chip_info->num_channels; i++)
+		st->pwr_down_mode |= (0x01 << (i * 2));
 
 	indio_dev->dev.parent = dev;
 	indio_dev->name = name;
@@ -319,8 +411,29 @@ int ad5686_probe(struct device *dev,
 	indio_dev->channels = st->chip_info->channels;
 	indio_dev->num_channels = st->chip_info->num_channels;
 
-	ret = st->write(st, AD5686_CMD_INTERNAL_REFER_SETUP,
-			0, !!voltage_uv);
+	switch (st->chip_info->regmap_type) {
+	case AD5683_REGMAP:
+		cmd = AD5686_CMD_CONTROL_REG;
+		ref_bit_msk = AD5683_REF_BIT_MSK;
+		st->use_internal_vref = !voltage_uv;
+		break;
+	case AD5686_REGMAP:
+		cmd = AD5686_CMD_INTERNAL_REFER_SETUP;
+		ref_bit_msk = 0;
+		break;
+	case AD5693_REGMAP:
+		cmd = AD5686_CMD_CONTROL_REG;
+		ref_bit_msk = AD5693_REF_BIT_MSK;
+		st->use_internal_vref = !voltage_uv;
+		break;
+	default:
+		ret = -EINVAL;
+		goto error_disable_reg;
+	}
+
+	val = (voltage_uv | ref_bit_msk);
+
+	ret = st->write(st, cmd, 0, !!val);
 	if (ret)
 		goto error_disable_reg;
 

+ 24 - 0
drivers/iio/dac/ad5686.h

@@ -13,6 +13,7 @@
 #include <linux/mutex.h>
 #include <linux/kernel.h>
 
+#define AD5683_DATA(x)				((x) << 4)
 #define AD5686_ADDR(x)				((x) << 16)
 #define AD5686_CMD(x)				((x) << 20)
 
@@ -35,6 +36,11 @@
 #define AD5686_LDAC_PWRDN_100K			0x2
 #define AD5686_LDAC_PWRDN_3STATE		0x3
 
+#define AD5686_CMD_CONTROL_REG			0x4
+#define AD5686_CMD_READBACK_ENABLE_V2		0x5
+#define AD5683_REF_BIT_MSK			BIT(12)
+#define AD5693_REF_BIT_MSK			BIT(12)
+
 /**
  * ad5686_supported_device_ids:
  */
@@ -44,11 +50,19 @@ enum ad5686_supported_device_ids {
 	ID_AD5675R,
 	ID_AD5676,
 	ID_AD5676R,
+	ID_AD5681R,
+	ID_AD5682R,
+	ID_AD5683,
+	ID_AD5683R,
 	ID_AD5684,
 	ID_AD5684R,
 	ID_AD5685R,
 	ID_AD5686,
 	ID_AD5686R,
+	ID_AD5691R,
+	ID_AD5692R,
+	ID_AD5693,
+	ID_AD5693R,
 	ID_AD5694,
 	ID_AD5694R,
 	ID_AD5695R,
@@ -56,6 +70,12 @@ enum ad5686_supported_device_ids {
 	ID_AD5696R,
 };
 
+enum ad5686_regmap_type {
+	AD5683_REGMAP,
+	AD5686_REGMAP,
+	AD5693_REGMAP
+};
+
 struct ad5686_state;
 
 typedef int (*ad5686_write_func)(struct ad5686_state *st,
@@ -68,12 +88,14 @@ typedef int (*ad5686_read_func)(struct ad5686_state *st, u8 addr);
  * @int_vref_mv:	AD5620/40/60: the internal reference voltage
  * @num_channels:	number of channels
  * @channel:		channel specification
+ * @regmap_type:	register map layout variant
  */
 
 struct ad5686_chip_info {
 	u16				int_vref_mv;
 	unsigned int			num_channels;
 	struct iio_chan_spec		*channels;
+	enum ad5686_regmap_type		regmap_type;
 };
 
 /**
@@ -84,6 +106,7 @@ struct ad5686_chip_info {
  * @vref_mv:		actual reference voltage used
  * @pwr_down_mask:	power down mask
  * @pwr_down_mode:	current power down mode
+ * @use_internal_vref:	set to true if the internal reference voltage is used
  * @data:		spi transfer buffers
  */
 
@@ -96,6 +119,7 @@ struct ad5686_state {
 	unsigned int			pwr_down_mode;
 	ad5686_write_func		write;
 	ad5686_read_func		read;
+	bool				use_internal_vref;
 
 	/*
 	 * DMA (thus cache coherency maintenance) requires the

+ 6 - 1
drivers/iio/dac/ad5696-i2c.c

@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * AD5671R, AD5675R, AD5694, AD5694R, AD5695R, AD5696, AD5696R
+ * AD5671R, AD5675R, AD5691R, AD5692R, AD5693, AD5693R,
+ * AD5694, AD5694R, AD5695R, AD5696, AD5696R
  * Digital to analog converters driver
  *
  * Copyright 2018 Analog Devices Inc.
@@ -72,6 +73,10 @@ static int ad5686_i2c_remove(struct i2c_client *i2c)
 static const struct i2c_device_id ad5686_i2c_id[] = {
 	{"ad5671r", ID_AD5671R},
 	{"ad5675r", ID_AD5675R},
+	{"ad5691r", ID_AD5691R},
+	{"ad5692r", ID_AD5692R},
+	{"ad5693", ID_AD5693},
+	{"ad5693r", ID_AD5693R},
 	{"ad5694", ID_AD5694},
 	{"ad5694r", ID_AD5694R},
 	{"ad5695r", ID_AD5695R},

+ 71 - 18
drivers/iio/dac/ltc2632.c

@@ -2,6 +2,7 @@
  * LTC2632 Digital to analog convertors spi driver
  *
  * Copyright 2017 Maxime Roussin-Bélanger
+ * expanded by Silvan Murer <silvan.murer@gmail.com>
  *
  * Licensed under the GPL-2.
  */
@@ -10,6 +11,7 @@
 #include <linux/spi/spi.h>
 #include <linux/module.h>
 #include <linux/iio/iio.h>
+#include <linux/regulator/consumer.h>
 
 #define LTC2632_DAC_CHANNELS                    2
 
@@ -28,7 +30,7 @@
 /**
  * struct ltc2632_chip_info - chip specific information
  * @channels:		channel spec for the DAC
- * @vref_mv:		reference voltage
+ * @vref_mv:		internal reference voltage
  */
 struct ltc2632_chip_info {
 	const struct iio_chan_spec *channels;
@@ -39,10 +41,14 @@ struct ltc2632_chip_info {
  * struct ltc2632_state - driver instance specific data
  * @spi_dev:			pointer to the spi_device struct
  * @powerdown_cache_mask	used to show current channel powerdown state
+ * @vref_mv			used reference voltage (internal or external)
+ * @vref_reg		regulator for the reference voltage
  */
 struct ltc2632_state {
 	struct spi_device *spi_dev;
 	unsigned int powerdown_cache_mask;
+	int vref_mv;
+	struct regulator *vref_reg;
 };
 
 enum ltc2632_supported_device_ids {
@@ -90,7 +96,7 @@ static int ltc2632_read_raw(struct iio_dev *indio_dev,
 
 	switch (m) {
 	case IIO_CHAN_INFO_SCALE:
-		*val = chip_info->vref_mv;
+		*val = st->vref_mv;
 		*val2 = chan->scan_type.realbits;
 		return IIO_VAL_FRACTIONAL_LOG2;
 	}
@@ -246,6 +252,45 @@ static int ltc2632_probe(struct spi_device *spi)
 	chip_info = (struct ltc2632_chip_info *)
 			spi_get_device_id(spi)->driver_data;
 
+	st->vref_reg = devm_regulator_get_optional(&spi->dev, "vref");
+	if (PTR_ERR(st->vref_reg) == -ENODEV) {
+		/* use internal reference voltage */
+		st->vref_reg = NULL;
+		st->vref_mv = chip_info->vref_mv;
+
+		ret = ltc2632_spi_write(spi, LTC2632_CMD_INTERNAL_REFER,
+				0, 0, 0);
+		if (ret) {
+			dev_err(&spi->dev,
+				"Set internal reference command failed, %d\n",
+				ret);
+			return ret;
+		}
+	} else if (IS_ERR(st->vref_reg)) {
+		dev_err(&spi->dev,
+				"Error getting voltage reference regulator\n");
+		return PTR_ERR(st->vref_reg);
+	} else {
+		/* use external reference voltage */
+		ret = regulator_enable(st->vref_reg);
+		if (ret) {
+			dev_err(&spi->dev,
+				"enable reference regulator failed, %d\n",
+				ret);
+			return ret;
+		}
+		st->vref_mv = regulator_get_voltage(st->vref_reg) / 1000;
+
+		ret = ltc2632_spi_write(spi, LTC2632_CMD_EXTERNAL_REFER,
+				0, 0, 0);
+		if (ret) {
+			dev_err(&spi->dev,
+				"Set external reference command failed, %d\n",
+				ret);
+			return ret;
+		}
+	}
+
 	indio_dev->dev.parent = &spi->dev;
 	indio_dev->name = dev_of_node(&spi->dev) ? dev_of_node(&spi->dev)->name
 						 : spi_get_device_id(spi)->name;
@@ -254,14 +299,20 @@ static int ltc2632_probe(struct spi_device *spi)
 	indio_dev->channels = chip_info->channels;
 	indio_dev->num_channels = LTC2632_DAC_CHANNELS;
 
-	ret = ltc2632_spi_write(spi, LTC2632_CMD_INTERNAL_REFER, 0, 0, 0);
-	if (ret) {
-		dev_err(&spi->dev,
-			"Set internal reference command failed, %d\n", ret);
-		return ret;
-	}
+	return iio_device_register(indio_dev);
+}
 
-	return devm_iio_device_register(&spi->dev, indio_dev);
+static int ltc2632_remove(struct spi_device *spi)
+{
+	struct iio_dev *indio_dev = spi_get_drvdata(spi);
+	struct ltc2632_state *st = iio_priv(indio_dev);
+
+	iio_device_unregister(indio_dev);
+
+	if (st->vref_reg)
+		regulator_disable(st->vref_reg);
+
+	return 0;
 }
 
 static const struct spi_device_id ltc2632_id[] = {
@@ -275,15 +326,6 @@ static const struct spi_device_id ltc2632_id[] = {
 };
 MODULE_DEVICE_TABLE(spi, ltc2632_id);
 
-static struct spi_driver ltc2632_driver = {
-	.driver		= {
-		.name	= "ltc2632",
-	},
-	.probe		= ltc2632_probe,
-	.id_table	= ltc2632_id,
-};
-module_spi_driver(ltc2632_driver);
-
 static const struct of_device_id ltc2632_of_match[] = {
 	{
 		.compatible = "lltc,ltc2632-l12",
@@ -308,6 +350,17 @@ static const struct of_device_id ltc2632_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, ltc2632_of_match);
 
+static struct spi_driver ltc2632_driver = {
+	.driver		= {
+		.name	= "ltc2632",
+		.of_match_table = of_match_ptr(ltc2632_of_match),
+	},
+	.probe		= ltc2632_probe,
+	.remove		= ltc2632_remove,
+	.id_table	= ltc2632_id,
+};
+module_spi_driver(ltc2632_driver);
+
 MODULE_AUTHOR("Maxime Roussin-Belanger <maxime.roussinbelanger@gmail.com>");
 MODULE_DESCRIPTION("LTC2632 DAC SPI driver");
 MODULE_LICENSE("GPL v2");

+ 8 - 1
drivers/iio/imu/inv_mpu6050/inv_mpu_core.c

@@ -798,7 +798,14 @@ static const struct iio_chan_spec inv_mpu_channels[] = {
 	INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Z, INV_MPU6050_SCAN_ACCL_Z),
 };
 
-/* constant IIO attribute */
+/*
+ * The user can choose any frequency between INV_MPU6050_MIN_FIFO_RATE and
+ * INV_MPU6050_MAX_FIFO_RATE, but only these frequencies are matched by the
+ * low-pass filter. Specifically, each of these sampling rates are about twice
+ * the bandwidth of a corresponding low-pass filter, which should eliminate
+ * aliasing following the Nyquist principle. By picking a frequency different
+ * from these, the user risks aliasing effects.
+ */
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("10 20 50 100 200 500");
 static IIO_CONST_ATTR(in_anglvel_scale_available,
 					  "0.000133090 0.000266181 0.000532362 0.001064724");

+ 2 - 2
drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c

@@ -175,7 +175,7 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
 	if (kfifo_len(&st->timestamps) >
 	    fifo_count / bytes_per_datum + INV_MPU6050_TIME_STAMP_TOR)
 		goto flush_fifo;
-	while (fifo_count >= bytes_per_datum) {
+	do {
 		result = regmap_bulk_read(st->map, st->reg->fifo_r_w,
 					  data, bytes_per_datum);
 		if (result)
@@ -194,7 +194,7 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
 							   timestamp);
 
 		fifo_count -= bytes_per_datum;
-	}
+	} while (fifo_count >= bytes_per_datum);
 
 end_session:
 	mutex_unlock(&st->lock);

+ 8 - 0
drivers/iio/light/Kconfig

@@ -409,6 +409,14 @@ config TSL2583
 	 Provides support for the TAOS tsl2580, tsl2581 and tsl2583 devices.
 	 Access ALS data via iio, sysfs.
 
+config TSL2772
+	tristate "TAOS TSL/TMD2x71 and TSL/TMD2x72 Family of light and proximity sensors"
+	depends on I2C
+	help
+	 Support for: tsl2571, tsl2671, tmd2671, tsl2771, tmd2771, tsl2572, tsl2672,
+	 tmd2672, tsl2772, tmd2772 devices.
+	 Provides iio_events and direct access via sysfs.
+
 config TSL4531
 	tristate "TAOS TSL4531 ambient light sensors"
 	depends on I2C

+ 1 - 0
drivers/iio/light/Makefile

@@ -40,6 +40,7 @@ obj-$(CONFIG_ST_UVIS25_SPI)	+= st_uvis25_spi.o
 obj-$(CONFIG_TCS3414)		+= tcs3414.o
 obj-$(CONFIG_TCS3472)		+= tcs3472.o
 obj-$(CONFIG_TSL2583)		+= tsl2583.o
+obj-$(CONFIG_TSL2772)		+= tsl2772.o
 obj-$(CONFIG_TSL4531)		+= tsl4531.o
 obj-$(CONFIG_US5182D)		+= us5182d.o
 obj-$(CONFIG_VCNL4000)		+= vcnl4000.o

+ 1 - 1
drivers/iio/light/tsl2583.c

@@ -600,7 +600,7 @@ done:
 
 static IIO_CONST_ATTR(in_illuminance_calibscale_available, "1 8 16 111");
 static IIO_CONST_ATTR(in_illuminance_integration_time_available,
-		      "0.000050 0.000100 0.000150 0.000200 0.000250 0.000300 0.000350 0.000400 0.000450 0.000500 0.000550 0.000600 0.000650");
+		      "0.050 0.100 0.150 0.200 0.250 0.300 0.350 0.400 0.450 0.500 0.550 0.600 0.650");
 static IIO_DEVICE_ATTR_RW(in_illuminance_input_target, 0);
 static IIO_DEVICE_ATTR_WO(in_illuminance_calibrate, 0);
 static IIO_DEVICE_ATTR_RW(in_illuminance_lux_table, 0);

+ 460 - 426
drivers/staging/iio/light/tsl2x7x.c → drivers/iio/light/tsl2772.c

@@ -1,7 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
  * Device driver for monitoring ambient light intensity in (lux) and proximity
- * detection (prox) within the TAOS TSL2X7X family of devices.
+ * detection (prox) within the TAOS TSL2571, TSL2671, TMD2671, TSL2771, TMD2771,
+ * TSL2572, TSL2672, TMD2672, TSL2772, and TMD2772 devices.
  *
  * Copyright (c) 2012, TAOS Corporation.
  * Copyright (c) 2017-2018 Brian Masney <masneyb@onstation.org>
@@ -18,94 +19,95 @@
 #include <linux/iio/events.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
-#include "tsl2x7x.h"
+#include <linux/platform_data/tsl2772.h>
 
 /* Cal defs */
 #define PROX_STAT_CAL			0
 #define PROX_STAT_SAMP			1
 #define MAX_SAMPLES_CAL			200
 
-/* TSL2X7X Device ID */
+/* TSL2772 Device ID */
 #define TRITON_ID			0x00
 #define SWORDFISH_ID			0x30
 #define HALIBUT_ID			0x20
 
 /* Lux calculation constants */
-#define TSL2X7X_LUX_CALC_OVER_FLOW	65535
+#define TSL2772_LUX_CALC_OVER_FLOW	65535
 
 /*
  * TAOS Register definitions - Note: depending on device, some of these register
  * are not used and the register address is benign.
  */
 
-/* 2X7X register offsets */
-#define TSL2X7X_MAX_CONFIG_REG		16
+/* Register offsets */
+#define TSL2772_MAX_CONFIG_REG		16
 
 /* Device Registers and Masks */
-#define TSL2X7X_CNTRL			0x00
-#define TSL2X7X_ALS_TIME		0X01
-#define TSL2X7X_PRX_TIME		0x02
-#define TSL2X7X_WAIT_TIME		0x03
-#define TSL2X7X_ALS_MINTHRESHLO		0X04
-#define TSL2X7X_ALS_MINTHRESHHI		0X05
-#define TSL2X7X_ALS_MAXTHRESHLO		0X06
-#define TSL2X7X_ALS_MAXTHRESHHI		0X07
-#define TSL2X7X_PRX_MINTHRESHLO		0X08
-#define TSL2X7X_PRX_MINTHRESHHI		0X09
-#define TSL2X7X_PRX_MAXTHRESHLO		0X0A
-#define TSL2X7X_PRX_MAXTHRESHHI		0X0B
-#define TSL2X7X_PERSISTENCE		0x0C
-#define TSL2X7X_ALS_PRX_CONFIG		0x0D
-#define TSL2X7X_PRX_COUNT		0x0E
-#define TSL2X7X_GAIN			0x0F
-#define TSL2X7X_NOTUSED			0x10
-#define TSL2X7X_REVID			0x11
-#define TSL2X7X_CHIPID			0x12
-#define TSL2X7X_STATUS			0x13
-#define TSL2X7X_ALS_CHAN0LO		0x14
-#define TSL2X7X_ALS_CHAN0HI		0x15
-#define TSL2X7X_ALS_CHAN1LO		0x16
-#define TSL2X7X_ALS_CHAN1HI		0x17
-#define TSL2X7X_PRX_LO			0x18
-#define TSL2X7X_PRX_HI			0x19
-
-/* tsl2X7X cmd reg masks */
-#define TSL2X7X_CMD_REG			0x80
-#define TSL2X7X_CMD_SPL_FN		0x60
-#define TSL2X7X_CMD_REPEAT_PROTO	0x00
-#define TSL2X7X_CMD_AUTOINC_PROTO	0x20
-
-#define TSL2X7X_CMD_PROX_INT_CLR	0X05
-#define TSL2X7X_CMD_ALS_INT_CLR		0x06
-#define TSL2X7X_CMD_PROXALS_INT_CLR	0X07
-
-/* tsl2X7X cntrl reg masks */
-#define TSL2X7X_CNTL_ADC_ENBL		0x02
-#define TSL2X7X_CNTL_PWR_ON		0x01
-
-/* tsl2X7X status reg masks */
-#define TSL2X7X_STA_ADC_VALID		0x01
-#define TSL2X7X_STA_PRX_VALID		0x02
-#define TSL2X7X_STA_ADC_PRX_VALID	(TSL2X7X_STA_ADC_VALID | \
-					 TSL2X7X_STA_PRX_VALID)
-#define TSL2X7X_STA_ALS_INTR		0x10
-#define TSL2X7X_STA_PRX_INTR		0x20
-
-/* tsl2X7X cntrl reg masks */
-#define TSL2X7X_CNTL_REG_CLEAR		0x00
-#define TSL2X7X_CNTL_PROX_INT_ENBL	0X20
-#define TSL2X7X_CNTL_ALS_INT_ENBL	0X10
-#define TSL2X7X_CNTL_WAIT_TMR_ENBL	0X08
-#define TSL2X7X_CNTL_PROX_DET_ENBL	0X04
-#define TSL2X7X_CNTL_PWRON		0x01
-#define TSL2X7X_CNTL_ALSPON_ENBL	0x03
-#define TSL2X7X_CNTL_INTALSPON_ENBL	0x13
-#define TSL2X7X_CNTL_PROXPON_ENBL	0x0F
-#define TSL2X7X_CNTL_INTPROXPON_ENBL	0x2F
-
-#define TSL2X7X_MIN_ITIME		3
-
-/* TAOS txx2x7x Device family members */
+#define TSL2772_CNTRL			0x00
+#define TSL2772_ALS_TIME		0X01
+#define TSL2772_PRX_TIME		0x02
+#define TSL2772_WAIT_TIME		0x03
+#define TSL2772_ALS_MINTHRESHLO		0X04
+#define TSL2772_ALS_MINTHRESHHI		0X05
+#define TSL2772_ALS_MAXTHRESHLO		0X06
+#define TSL2772_ALS_MAXTHRESHHI		0X07
+#define TSL2772_PRX_MINTHRESHLO		0X08
+#define TSL2772_PRX_MINTHRESHHI		0X09
+#define TSL2772_PRX_MAXTHRESHLO		0X0A
+#define TSL2772_PRX_MAXTHRESHHI		0X0B
+#define TSL2772_PERSISTENCE		0x0C
+#define TSL2772_ALS_PRX_CONFIG		0x0D
+#define TSL2772_PRX_COUNT		0x0E
+#define TSL2772_GAIN			0x0F
+#define TSL2772_NOTUSED			0x10
+#define TSL2772_REVID			0x11
+#define TSL2772_CHIPID			0x12
+#define TSL2772_STATUS			0x13
+#define TSL2772_ALS_CHAN0LO		0x14
+#define TSL2772_ALS_CHAN0HI		0x15
+#define TSL2772_ALS_CHAN1LO		0x16
+#define TSL2772_ALS_CHAN1HI		0x17
+#define TSL2772_PRX_LO			0x18
+#define TSL2772_PRX_HI			0x19
+
+/* tsl2772 cmd reg masks */
+#define TSL2772_CMD_REG			0x80
+#define TSL2772_CMD_SPL_FN		0x60
+#define TSL2772_CMD_REPEAT_PROTO	0x00
+#define TSL2772_CMD_AUTOINC_PROTO	0x20
+
+#define TSL2772_CMD_PROX_INT_CLR	0X05
+#define TSL2772_CMD_ALS_INT_CLR		0x06
+#define TSL2772_CMD_PROXALS_INT_CLR	0X07
+
+/* tsl2772 cntrl reg masks */
+#define TSL2772_CNTL_ADC_ENBL		0x02
+#define TSL2772_CNTL_PWR_ON		0x01
+
+/* tsl2772 status reg masks */
+#define TSL2772_STA_ADC_VALID		0x01
+#define TSL2772_STA_PRX_VALID		0x02
+#define TSL2772_STA_ADC_PRX_VALID	(TSL2772_STA_ADC_VALID | \
+					 TSL2772_STA_PRX_VALID)
+#define TSL2772_STA_ALS_INTR		0x10
+#define TSL2772_STA_PRX_INTR		0x20
+
+/* tsl2772 cntrl reg masks */
+#define TSL2772_CNTL_REG_CLEAR		0x00
+#define TSL2772_CNTL_PROX_INT_ENBL	0X20
+#define TSL2772_CNTL_ALS_INT_ENBL	0X10
+#define TSL2772_CNTL_WAIT_TMR_ENBL	0X08
+#define TSL2772_CNTL_PROX_DET_ENBL	0X04
+#define TSL2772_CNTL_PWRON		0x01
+#define TSL2772_CNTL_ALSPON_ENBL	0x03
+#define TSL2772_CNTL_INTALSPON_ENBL	0x13
+#define TSL2772_CNTL_PROXPON_ENBL	0x0F
+#define TSL2772_CNTL_INTPROXPON_ENBL	0x2F
+
+#define TSL2772_ALS_GAIN_TRIM_MIN	250
+#define TSL2772_ALS_GAIN_TRIM_MAX	4000
+
+/* Device family members */
 enum {
 	tsl2571,
 	tsl2671,
@@ -120,39 +122,39 @@ enum {
 };
 
 enum {
-	TSL2X7X_CHIP_UNKNOWN = 0,
-	TSL2X7X_CHIP_WORKING = 1,
-	TSL2X7X_CHIP_SUSPENDED = 2
+	TSL2772_CHIP_UNKNOWN = 0,
+	TSL2772_CHIP_WORKING = 1,
+	TSL2772_CHIP_SUSPENDED = 2
 };
 
 /* Per-device data */
-struct tsl2x7x_als_info {
+struct tsl2772_als_info {
 	u16 als_ch0;
 	u16 als_ch1;
 	u16 lux;
 };
 
-struct tsl2x7x_chip_info {
+struct tsl2772_chip_info {
 	int chan_table_elements;
 	struct iio_chan_spec channel_with_events[4];
 	struct iio_chan_spec channel_without_events[4];
 	const struct iio_info *info;
 };
 
-struct tsl2X7X_chip {
+struct tsl2772_chip {
 	kernel_ulong_t id;
 	struct mutex prox_mutex;
 	struct mutex als_mutex;
 	struct i2c_client *client;
 	u16 prox_data;
-	struct tsl2x7x_als_info als_cur_info;
-	struct tsl2x7x_settings settings;
-	struct tsl2X7X_platform_data *pdata;
+	struct tsl2772_als_info als_cur_info;
+	struct tsl2772_settings settings;
+	struct tsl2772_platform_data *pdata;
 	int als_gain_time_scale;
 	int als_saturation;
-	int tsl2x7x_chip_status;
-	u8 tsl2x7x_config[TSL2X7X_MAX_CONFIG_REG];
-	const struct tsl2x7x_chip_info	*chip_info;
+	int tsl2772_chip_status;
+	u8 tsl2772_config[TSL2772_MAX_CONFIG_REG];
+	const struct tsl2772_chip_info	*chip_info;
 	const struct iio_info *info;
 	s64 event_timestamp;
 	/*
@@ -160,7 +162,7 @@ struct tsl2X7X_chip {
 	 * updates via sysfs.
 	 * Sized to 9 = max 8 segments + 1 termination segment
 	 */
-	struct tsl2x7x_lux tsl2x7x_device_lux[TSL2X7X_MAX_LUX_TABLE_SIZE];
+	struct tsl2772_lux tsl2772_device_lux[TSL2772_MAX_LUX_TABLE_SIZE];
 };
 
 /*
@@ -171,47 +173,47 @@ struct tsl2X7X_chip {
  * The two rows in each table correspond to the Lux1 and Lux2 equations from
  * the datasheets.
  */
-static const struct tsl2x7x_lux tsl2x71_lux_table[TSL2X7X_DEF_LUX_TABLE_SZ] = {
+static const struct tsl2772_lux tsl2x71_lux_table[TSL2772_DEF_LUX_TABLE_SZ] = {
 	{ 53000, 106000 },
 	{ 31800,  53000 },
 	{ 0,          0 },
 };
 
-static const struct tsl2x7x_lux tmd2x71_lux_table[TSL2X7X_DEF_LUX_TABLE_SZ] = {
+static const struct tsl2772_lux tmd2x71_lux_table[TSL2772_DEF_LUX_TABLE_SZ] = {
 	{ 24000,  48000 },
 	{ 14400,  24000 },
 	{ 0,          0 },
 };
 
-static const struct tsl2x7x_lux tsl2x72_lux_table[TSL2X7X_DEF_LUX_TABLE_SZ] = {
+static const struct tsl2772_lux tsl2x72_lux_table[TSL2772_DEF_LUX_TABLE_SZ] = {
 	{ 60000, 112200 },
 	{ 37800,  60000 },
 	{     0,      0 },
 };
 
-static const struct tsl2x7x_lux tmd2x72_lux_table[TSL2X7X_DEF_LUX_TABLE_SZ] = {
+static const struct tsl2772_lux tmd2x72_lux_table[TSL2772_DEF_LUX_TABLE_SZ] = {
 	{ 20000,  35000 },
 	{ 12600,  20000 },
 	{     0,      0 },
 };
 
-static const struct tsl2x7x_lux *tsl2x7x_default_lux_table_group[] = {
-	[tsl2571] =	tsl2x71_lux_table,
-	[tsl2671] =	tsl2x71_lux_table,
-	[tmd2671] =	tmd2x71_lux_table,
-	[tsl2771] =	tsl2x71_lux_table,
-	[tmd2771] =	tmd2x71_lux_table,
-	[tsl2572] =	tsl2x72_lux_table,
-	[tsl2672] =	tsl2x72_lux_table,
-	[tmd2672] =	tmd2x72_lux_table,
-	[tsl2772] =	tsl2x72_lux_table,
-	[tmd2772] =	tmd2x72_lux_table,
+static const struct tsl2772_lux *tsl2772_default_lux_table_group[] = {
+	[tsl2571] = tsl2x71_lux_table,
+	[tsl2671] = tsl2x71_lux_table,
+	[tmd2671] = tmd2x71_lux_table,
+	[tsl2771] = tsl2x71_lux_table,
+	[tmd2771] = tmd2x71_lux_table,
+	[tsl2572] = tsl2x72_lux_table,
+	[tsl2672] = tsl2x72_lux_table,
+	[tmd2672] = tmd2x72_lux_table,
+	[tsl2772] = tsl2x72_lux_table,
+	[tmd2772] = tmd2x72_lux_table,
 };
 
-static const struct tsl2x7x_settings tsl2x7x_default_settings = {
-	.als_time = 255, /* 2.73 ms */
+static const struct tsl2772_settings tsl2772_default_settings = {
+	.als_time = 255, /* 2.72 / 2.73 ms */
 	.als_gain = 0,
-	.prox_time = 255, /* 2.73 ms */
+	.prox_time = 255, /* 2.72 / 2.73 ms */
 	.prox_gain = 0,
 	.wait_time = 255,
 	.als_prox_config = 0,
@@ -227,24 +229,41 @@ static const struct tsl2x7x_settings tsl2x7x_default_settings = {
 	.prox_thres_high = 512,
 	.prox_max_samples_cal = 30,
 	.prox_pulse_count = 8,
-	.prox_diode = TSL2X7X_DIODE1,
-	.prox_power = TSL2X7X_100_mA
+	.prox_diode = TSL2772_DIODE1,
+	.prox_power = TSL2772_100_mA
 };
 
-static const s16 tsl2x7x_als_gain[] = {
+static const s16 tsl2772_als_gain[] = {
 	1,
 	8,
 	16,
 	120
 };
 
-static const s16 tsl2x7x_prox_gain[] = {
+static const s16 tsl2772_prox_gain[] = {
 	1,
 	2,
 	4,
 	8
 };
 
+static const int tsl2772_int_time_avail[][6] = {
+	[tsl2571] = { 0, 2720, 0, 2720, 0, 696000 },
+	[tsl2671] = { 0, 2720, 0, 2720, 0, 696000 },
+	[tmd2671] = { 0, 2720, 0, 2720, 0, 696000 },
+	[tsl2771] = { 0, 2720, 0, 2720, 0, 696000 },
+	[tmd2771] = { 0, 2720, 0, 2720, 0, 696000 },
+	[tsl2572] = { 0, 2730, 0, 2730, 0, 699000 },
+	[tsl2672] = { 0, 2730, 0, 2730, 0, 699000 },
+	[tmd2672] = { 0, 2730, 0, 2730, 0, 699000 },
+	[tsl2772] = { 0, 2730, 0, 2730, 0, 699000 },
+	[tmd2772] = { 0, 2730, 0, 2730, 0, 699000 },
+};
+
+static int tsl2772_int_calibscale_avail[] = { 1, 8, 16, 120 };
+
+static int tsl2772_prox_calibscale_avail[] = { 1, 2, 4, 8 };
+
 /* Channel variations */
 enum {
 	ALS,
@@ -267,12 +286,12 @@ static const u8 device_channel_config[] = {
 	[tmd2772] = ALSPRX2
 };
 
-static int tsl2x7x_read_status(struct tsl2X7X_chip *chip)
+static int tsl2772_read_status(struct tsl2772_chip *chip)
 {
 	int ret;
 
 	ret = i2c_smbus_read_byte_data(chip->client,
-				       TSL2X7X_CMD_REG | TSL2X7X_STATUS);
+				       TSL2772_CMD_REG | TSL2772_STATUS);
 	if (ret < 0)
 		dev_err(&chip->client->dev,
 			"%s: failed to read STATUS register: %d\n", __func__,
@@ -281,12 +300,12 @@ static int tsl2x7x_read_status(struct tsl2X7X_chip *chip)
 	return ret;
 }
 
-static int tsl2x7x_write_control_reg(struct tsl2X7X_chip *chip, u8 data)
+static int tsl2772_write_control_reg(struct tsl2772_chip *chip, u8 data)
 {
 	int ret;
 
 	ret = i2c_smbus_write_byte_data(chip->client,
-					TSL2X7X_CMD_REG | TSL2X7X_CNTRL, data);
+					TSL2772_CMD_REG | TSL2772_CNTRL, data);
 	if (ret < 0) {
 		dev_err(&chip->client->dev,
 			"%s: failed to write to control register %x: %d\n",
@@ -296,14 +315,14 @@ static int tsl2x7x_write_control_reg(struct tsl2X7X_chip *chip, u8 data)
 	return ret;
 }
 
-static int tsl2x7x_read_autoinc_regs(struct tsl2X7X_chip *chip, int lower_reg,
+static int tsl2772_read_autoinc_regs(struct tsl2772_chip *chip, int lower_reg,
 				     int upper_reg)
 {
 	u8 buf[2];
 	int ret;
 
 	ret = i2c_smbus_write_byte(chip->client,
-				   TSL2X7X_CMD_REG | TSL2X7X_CMD_AUTOINC_PROTO |
+				   TSL2772_CMD_REG | TSL2772_CMD_AUTOINC_PROTO |
 				   lower_reg);
 	if (ret < 0) {
 		dev_err(&chip->client->dev,
@@ -313,7 +332,7 @@ static int tsl2x7x_read_autoinc_regs(struct tsl2X7X_chip *chip, int lower_reg,
 	}
 
 	ret = i2c_smbus_read_byte_data(chip->client,
-				       TSL2X7X_CMD_REG | lower_reg);
+				       TSL2772_CMD_REG | lower_reg);
 	if (ret < 0) {
 		dev_err(&chip->client->dev,
 			"%s: failed to read from register %x: %d\n", __func__,
@@ -323,7 +342,7 @@ static int tsl2x7x_read_autoinc_regs(struct tsl2X7X_chip *chip, int lower_reg,
 	buf[0] = ret;
 
 	ret = i2c_smbus_read_byte_data(chip->client,
-				       TSL2X7X_CMD_REG | upper_reg);
+				       TSL2772_CMD_REG | upper_reg);
 	if (ret < 0) {
 		dev_err(&chip->client->dev,
 			"%s: failed to read from register %x: %d\n", __func__,
@@ -333,7 +352,7 @@ static int tsl2x7x_read_autoinc_regs(struct tsl2X7X_chip *chip, int lower_reg,
 	buf[1] = ret;
 
 	ret = i2c_smbus_write_byte(chip->client,
-				   TSL2X7X_CMD_REG | TSL2X7X_CMD_REPEAT_PROTO |
+				   TSL2772_CMD_REG | TSL2772_CMD_REPEAT_PROTO |
 				   lower_reg);
 	if (ret < 0) {
 		dev_err(&chip->client->dev,
@@ -346,7 +365,7 @@ static int tsl2x7x_read_autoinc_regs(struct tsl2X7X_chip *chip, int lower_reg,
 }
 
 /**
- * tsl2x7x_get_lux() - Reads and calculates current lux value.
+ * tsl2772_get_lux() - Reads and calculates current lux value.
  * @indio_dev:	pointer to IIO device
  *
  * The raw ch0 and ch1 values of the ambient light sensed in the last
@@ -356,47 +375,47 @@ static int tsl2x7x_read_autoinc_regs(struct tsl2X7X_chip *chip, int lower_reg,
  * coefficients. A lux gain trim is applied to each lux equation, and then the
  * maximum lux within the interval 0..65535 is selected.
  */
-static int tsl2x7x_get_lux(struct iio_dev *indio_dev)
+static int tsl2772_get_lux(struct iio_dev *indio_dev)
 {
-	struct tsl2X7X_chip *chip = iio_priv(indio_dev);
-	struct tsl2x7x_lux *p;
+	struct tsl2772_chip *chip = iio_priv(indio_dev);
+	struct tsl2772_lux *p;
 	int max_lux, ret;
 	bool overflow;
 
 	mutex_lock(&chip->als_mutex);
 
-	if (chip->tsl2x7x_chip_status != TSL2X7X_CHIP_WORKING) {
+	if (chip->tsl2772_chip_status != TSL2772_CHIP_WORKING) {
 		dev_err(&chip->client->dev, "%s: device is not enabled\n",
 			__func__);
 		ret = -EBUSY;
 		goto out_unlock;
 	}
 
-	ret = tsl2x7x_read_status(chip);
+	ret = tsl2772_read_status(chip);
 	if (ret < 0)
 		goto out_unlock;
 
-	if (!(ret & TSL2X7X_STA_ADC_VALID)) {
+	if (!(ret & TSL2772_STA_ADC_VALID)) {
 		dev_err(&chip->client->dev,
 			"%s: data not valid yet\n", __func__);
 		ret = chip->als_cur_info.lux; /* return LAST VALUE */
 		goto out_unlock;
 	}
 
-	ret = tsl2x7x_read_autoinc_regs(chip, TSL2X7X_ALS_CHAN0LO,
-					TSL2X7X_ALS_CHAN0HI);
+	ret = tsl2772_read_autoinc_regs(chip, TSL2772_ALS_CHAN0LO,
+					TSL2772_ALS_CHAN0HI);
 	if (ret < 0)
 		goto out_unlock;
 	chip->als_cur_info.als_ch0 = ret;
 
-	ret = tsl2x7x_read_autoinc_regs(chip, TSL2X7X_ALS_CHAN1LO,
-					TSL2X7X_ALS_CHAN1HI);
+	ret = tsl2772_read_autoinc_regs(chip, TSL2772_ALS_CHAN1LO,
+					TSL2772_ALS_CHAN1HI);
 	if (ret < 0)
 		goto out_unlock;
 	chip->als_cur_info.als_ch1 = ret;
 
 	if (chip->als_cur_info.als_ch0 >= chip->als_saturation) {
-		max_lux = TSL2X7X_LUX_CALC_OVER_FLOW;
+		max_lux = TSL2772_LUX_CALC_OVER_FLOW;
 		goto update_struct_with_max_lux;
 	}
 
@@ -408,7 +427,7 @@ static int tsl2x7x_get_lux(struct iio_dev *indio_dev)
 
 	max_lux = 0;
 	overflow = false;
-	for (p = (struct tsl2x7x_lux *)chip->tsl2x7x_device_lux; p->ch0 != 0;
+	for (p = (struct tsl2772_lux *)chip->tsl2772_device_lux; p->ch0 != 0;
 	     p++) {
 		int lux;
 
@@ -424,7 +443,7 @@ static int tsl2x7x_get_lux(struct iio_dev *indio_dev)
 		 */
 		lux = (lux * chip->settings.als_gain_trim) / 1000;
 
-		if (lux > TSL2X7X_LUX_CALC_OVER_FLOW) {
+		if (lux > TSL2772_LUX_CALC_OVER_FLOW) {
 			overflow = true;
 			continue;
 		}
@@ -433,7 +452,7 @@ static int tsl2x7x_get_lux(struct iio_dev *indio_dev)
 	}
 
 	if (overflow && max_lux == 0)
-		max_lux = TSL2X7X_LUX_CALC_OVER_FLOW;
+		max_lux = TSL2772_LUX_CALC_OVER_FLOW;
 
 update_struct_with_max_lux:
 	chip->als_cur_info.lux = max_lux;
@@ -446,19 +465,19 @@ out_unlock:
 }
 
 /**
- * tsl2x7x_get_prox() - Reads proximity data registers and updates
+ * tsl2772_get_prox() - Reads proximity data registers and updates
  *                      chip->prox_data.
  *
  * @indio_dev:	pointer to IIO device
  */
-static int tsl2x7x_get_prox(struct iio_dev *indio_dev)
+static int tsl2772_get_prox(struct iio_dev *indio_dev)
 {
-	struct tsl2X7X_chip *chip = iio_priv(indio_dev);
+	struct tsl2772_chip *chip = iio_priv(indio_dev);
 	int ret;
 
 	mutex_lock(&chip->prox_mutex);
 
-	ret = tsl2x7x_read_status(chip);
+	ret = tsl2772_read_status(chip);
 	if (ret < 0)
 		goto prox_poll_err;
 
@@ -468,7 +487,7 @@ static int tsl2x7x_get_prox(struct iio_dev *indio_dev)
 	case tmd2671:
 	case tsl2771:
 	case tmd2771:
-		if (!(ret & TSL2X7X_STA_ADC_VALID)) {
+		if (!(ret & TSL2772_STA_ADC_VALID)) {
 			ret = -EINVAL;
 			goto prox_poll_err;
 		}
@@ -478,14 +497,14 @@ static int tsl2x7x_get_prox(struct iio_dev *indio_dev)
 	case tmd2672:
 	case tsl2772:
 	case tmd2772:
-		if (!(ret & TSL2X7X_STA_PRX_VALID)) {
+		if (!(ret & TSL2772_STA_PRX_VALID)) {
 			ret = -EINVAL;
 			goto prox_poll_err;
 		}
 		break;
 	}
 
-	ret = tsl2x7x_read_autoinc_regs(chip, TSL2X7X_PRX_LO, TSL2X7X_PRX_HI);
+	ret = tsl2772_read_autoinc_regs(chip, TSL2772_PRX_LO, TSL2772_PRX_HI);
 	if (ret < 0)
 		goto prox_poll_err;
 	chip->prox_data = ret;
@@ -497,46 +516,46 @@ prox_poll_err:
 }
 
 /**
- * tsl2x7x_defaults() - Populates the device nominal operating parameters
+ * tsl2772_defaults() - Populates the device nominal operating parameters
  *                      with those provided by a 'platform' data struct or
  *                      with prefined defaults.
  *
  * @chip:               pointer to device structure.
  */
-static void tsl2x7x_defaults(struct tsl2X7X_chip *chip)
+static void tsl2772_defaults(struct tsl2772_chip *chip)
 {
 	/* If Operational settings defined elsewhere.. */
 	if (chip->pdata && chip->pdata->platform_default_settings)
 		memcpy(&chip->settings, chip->pdata->platform_default_settings,
-		       sizeof(tsl2x7x_default_settings));
+		       sizeof(tsl2772_default_settings));
 	else
-		memcpy(&chip->settings, &tsl2x7x_default_settings,
-		       sizeof(tsl2x7x_default_settings));
+		memcpy(&chip->settings, &tsl2772_default_settings,
+		       sizeof(tsl2772_default_settings));
 
 	/* Load up the proper lux table. */
 	if (chip->pdata && chip->pdata->platform_lux_table[0].ch0 != 0)
-		memcpy(chip->tsl2x7x_device_lux,
+		memcpy(chip->tsl2772_device_lux,
 		       chip->pdata->platform_lux_table,
 		       sizeof(chip->pdata->platform_lux_table));
 	else
-		memcpy(chip->tsl2x7x_device_lux,
-		       tsl2x7x_default_lux_table_group[chip->id],
-		       TSL2X7X_DEFAULT_TABLE_BYTES);
+		memcpy(chip->tsl2772_device_lux,
+		       tsl2772_default_lux_table_group[chip->id],
+		       TSL2772_DEFAULT_TABLE_BYTES);
 }
 
 /**
- * tsl2x7x_als_calibrate() -	Obtain single reading and calculate
+ * tsl2772_als_calibrate() -	Obtain single reading and calculate
  *                              the als_gain_trim.
  *
  * @indio_dev:	pointer to IIO device
  */
-static int tsl2x7x_als_calibrate(struct iio_dev *indio_dev)
+static int tsl2772_als_calibrate(struct iio_dev *indio_dev)
 {
-	struct tsl2X7X_chip *chip = iio_priv(indio_dev);
+	struct tsl2772_chip *chip = iio_priv(indio_dev);
 	int ret, lux_val;
 
 	ret = i2c_smbus_read_byte_data(chip->client,
-				       TSL2X7X_CMD_REG | TSL2X7X_CNTRL);
+				       TSL2772_CMD_REG | TSL2772_CNTRL);
 	if (ret < 0) {
 		dev_err(&chip->client->dev,
 			"%s: failed to read from the CNTRL register\n",
@@ -544,20 +563,20 @@ static int tsl2x7x_als_calibrate(struct iio_dev *indio_dev)
 		return ret;
 	}
 
-	if ((ret & (TSL2X7X_CNTL_ADC_ENBL | TSL2X7X_CNTL_PWR_ON))
-			!= (TSL2X7X_CNTL_ADC_ENBL | TSL2X7X_CNTL_PWR_ON)) {
+	if ((ret & (TSL2772_CNTL_ADC_ENBL | TSL2772_CNTL_PWR_ON))
+			!= (TSL2772_CNTL_ADC_ENBL | TSL2772_CNTL_PWR_ON)) {
 		dev_err(&chip->client->dev,
 			"%s: Device is not powered on and/or ADC is not enabled\n",
 			__func__);
 		return -EINVAL;
-	} else if ((ret & TSL2X7X_STA_ADC_VALID) != TSL2X7X_STA_ADC_VALID) {
+	} else if ((ret & TSL2772_STA_ADC_VALID) != TSL2772_STA_ADC_VALID) {
 		dev_err(&chip->client->dev,
 			"%s: The two ADC channels have not completed an integration cycle\n",
 			__func__);
 		return -ENODATA;
 	}
 
-	lux_val = tsl2x7x_get_lux(indio_dev);
+	lux_val = tsl2772_get_lux(indio_dev);
 	if (lux_val < 0) {
 		dev_err(&chip->client->dev,
 			"%s: failed to get lux\n", __func__);
@@ -566,7 +585,7 @@ static int tsl2x7x_als_calibrate(struct iio_dev *indio_dev)
 
 	ret = (chip->settings.als_cal_target * chip->settings.als_gain_trim) /
 			lux_val;
-	if (ret < 250 || ret > 4000)
+	if (ret < TSL2772_ALS_GAIN_TRIM_MIN || ret > TSL2772_ALS_GAIN_TRIM_MAX)
 		return -ERANGE;
 
 	chip->settings.als_gain_trim = ret;
@@ -574,51 +593,51 @@ static int tsl2x7x_als_calibrate(struct iio_dev *indio_dev)
 	return ret;
 }
 
-static int tsl2x7x_chip_on(struct iio_dev *indio_dev)
+static int tsl2772_chip_on(struct iio_dev *indio_dev)
 {
-	struct tsl2X7X_chip *chip = iio_priv(indio_dev);
+	struct tsl2772_chip *chip = iio_priv(indio_dev);
 	int ret, i, als_count, als_time_us;
 	u8 *dev_reg, reg_val;
 
 	/* Non calculated parameters */
-	chip->tsl2x7x_config[TSL2X7X_ALS_TIME] = chip->settings.als_time;
-	chip->tsl2x7x_config[TSL2X7X_PRX_TIME] = chip->settings.prox_time;
-	chip->tsl2x7x_config[TSL2X7X_WAIT_TIME] = chip->settings.wait_time;
-	chip->tsl2x7x_config[TSL2X7X_ALS_PRX_CONFIG] =
+	chip->tsl2772_config[TSL2772_ALS_TIME] = chip->settings.als_time;
+	chip->tsl2772_config[TSL2772_PRX_TIME] = chip->settings.prox_time;
+	chip->tsl2772_config[TSL2772_WAIT_TIME] = chip->settings.wait_time;
+	chip->tsl2772_config[TSL2772_ALS_PRX_CONFIG] =
 		chip->settings.als_prox_config;
 
-	chip->tsl2x7x_config[TSL2X7X_ALS_MINTHRESHLO] =
+	chip->tsl2772_config[TSL2772_ALS_MINTHRESHLO] =
 		(chip->settings.als_thresh_low) & 0xFF;
-	chip->tsl2x7x_config[TSL2X7X_ALS_MINTHRESHHI] =
+	chip->tsl2772_config[TSL2772_ALS_MINTHRESHHI] =
 		(chip->settings.als_thresh_low >> 8) & 0xFF;
-	chip->tsl2x7x_config[TSL2X7X_ALS_MAXTHRESHLO] =
+	chip->tsl2772_config[TSL2772_ALS_MAXTHRESHLO] =
 		(chip->settings.als_thresh_high) & 0xFF;
-	chip->tsl2x7x_config[TSL2X7X_ALS_MAXTHRESHHI] =
+	chip->tsl2772_config[TSL2772_ALS_MAXTHRESHHI] =
 		(chip->settings.als_thresh_high >> 8) & 0xFF;
-	chip->tsl2x7x_config[TSL2X7X_PERSISTENCE] =
+	chip->tsl2772_config[TSL2772_PERSISTENCE] =
 		(chip->settings.prox_persistence & 0xFF) << 4 |
 		(chip->settings.als_persistence & 0xFF);
 
-	chip->tsl2x7x_config[TSL2X7X_PRX_COUNT] =
+	chip->tsl2772_config[TSL2772_PRX_COUNT] =
 			chip->settings.prox_pulse_count;
-	chip->tsl2x7x_config[TSL2X7X_PRX_MINTHRESHLO] =
+	chip->tsl2772_config[TSL2772_PRX_MINTHRESHLO] =
 			(chip->settings.prox_thres_low) & 0xFF;
-	chip->tsl2x7x_config[TSL2X7X_PRX_MINTHRESHHI] =
+	chip->tsl2772_config[TSL2772_PRX_MINTHRESHHI] =
 			(chip->settings.prox_thres_low >> 8) & 0xFF;
-	chip->tsl2x7x_config[TSL2X7X_PRX_MAXTHRESHLO] =
+	chip->tsl2772_config[TSL2772_PRX_MAXTHRESHLO] =
 			(chip->settings.prox_thres_high) & 0xFF;
-	chip->tsl2x7x_config[TSL2X7X_PRX_MAXTHRESHHI] =
+	chip->tsl2772_config[TSL2772_PRX_MAXTHRESHHI] =
 			(chip->settings.prox_thres_high >> 8) & 0xFF;
 
 	/* and make sure we're not already on */
-	if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_WORKING) {
+	if (chip->tsl2772_chip_status == TSL2772_CHIP_WORKING) {
 		/* if forcing a register update - turn off, then on */
 		dev_info(&chip->client->dev, "device is already enabled\n");
 		return -EINVAL;
 	}
 
-	/* Set the gain based on tsl2x7x_settings struct */
-	chip->tsl2x7x_config[TSL2X7X_GAIN] =
+	/* Set the gain based on tsl2772_settings struct */
+	chip->tsl2772_config[TSL2772_GAIN] =
 		(chip->settings.als_gain & 0xFF) |
 		((chip->settings.prox_gain & 0xFF) << 2) |
 		(chip->settings.prox_diode << 4) |
@@ -626,16 +645,16 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev)
 
 	/* set chip time scaling and saturation */
 	als_count = 256 - chip->settings.als_time;
-	als_time_us = als_count * 2720;
+	als_time_us = als_count * tsl2772_int_time_avail[chip->id][3];
 	chip->als_saturation = als_count * 768; /* 75% of full scale */
 	chip->als_gain_time_scale = als_time_us *
-		tsl2x7x_als_gain[chip->settings.als_gain];
+		tsl2772_als_gain[chip->settings.als_gain];
 
 	/*
-	 * TSL2X7X Specific power-on / adc enable sequence
+	 * TSL2772 Specific power-on / adc enable sequence
 	 * Power on the device 1st.
 	 */
-	ret = tsl2x7x_write_control_reg(chip, TSL2X7X_CNTL_PWR_ON);
+	ret = tsl2772_write_control_reg(chip, TSL2772_CNTL_PWR_ON);
 	if (ret < 0)
 		return ret;
 
@@ -643,9 +662,9 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev)
 	 * Use the following shadow copy for our delay before enabling ADC.
 	 * Write all the registers.
 	 */
-	for (i = 0, dev_reg = chip->tsl2x7x_config;
-			i < TSL2X7X_MAX_CONFIG_REG; i++) {
-		int reg = TSL2X7X_CMD_REG + i;
+	for (i = 0, dev_reg = chip->tsl2772_config;
+			i < TSL2772_MAX_CONFIG_REG; i++) {
+		int reg = TSL2772_CMD_REG + i;
 
 		ret = i2c_smbus_write_byte_data(chip->client, reg,
 						*dev_reg++);
@@ -660,20 +679,20 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev)
 	/* Power-on settling time */
 	usleep_range(3000, 3500);
 
-	reg_val = TSL2X7X_CNTL_PWR_ON | TSL2X7X_CNTL_ADC_ENBL |
-		  TSL2X7X_CNTL_PROX_DET_ENBL;
+	reg_val = TSL2772_CNTL_PWR_ON | TSL2772_CNTL_ADC_ENBL |
+		  TSL2772_CNTL_PROX_DET_ENBL;
 	if (chip->settings.als_interrupt_en)
-		reg_val |= TSL2X7X_CNTL_ALS_INT_ENBL;
+		reg_val |= TSL2772_CNTL_ALS_INT_ENBL;
 	if (chip->settings.prox_interrupt_en)
-		reg_val |= TSL2X7X_CNTL_PROX_INT_ENBL;
+		reg_val |= TSL2772_CNTL_PROX_INT_ENBL;
 
-	ret = tsl2x7x_write_control_reg(chip, reg_val);
+	ret = tsl2772_write_control_reg(chip, reg_val);
 	if (ret < 0)
 		return ret;
 
 	ret = i2c_smbus_write_byte(chip->client,
-				   TSL2X7X_CMD_REG | TSL2X7X_CMD_SPL_FN |
-				   TSL2X7X_CMD_PROXALS_INT_CLR);
+				   TSL2772_CMD_REG | TSL2772_CMD_SPL_FN |
+				   TSL2772_CMD_PROXALS_INT_CLR);
 	if (ret < 0) {
 		dev_err(&chip->client->dev,
 			"%s: failed to clear interrupt status: %d\n",
@@ -681,22 +700,22 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev)
 		return ret;
 	}
 
-	chip->tsl2x7x_chip_status = TSL2X7X_CHIP_WORKING;
+	chip->tsl2772_chip_status = TSL2772_CHIP_WORKING;
 
 	return ret;
 }
 
-static int tsl2x7x_chip_off(struct iio_dev *indio_dev)
+static int tsl2772_chip_off(struct iio_dev *indio_dev)
 {
-	struct tsl2X7X_chip *chip = iio_priv(indio_dev);
+	struct tsl2772_chip *chip = iio_priv(indio_dev);
 
 	/* turn device off */
-	chip->tsl2x7x_chip_status = TSL2X7X_CHIP_SUSPENDED;
-	return tsl2x7x_write_control_reg(chip, 0x00);
+	chip->tsl2772_chip_status = TSL2772_CHIP_SUSPENDED;
+	return tsl2772_write_control_reg(chip, 0x00);
 }
 
 /**
- * tsl2x7x_invoke_change - power cycle the device to implement the user
+ * tsl2772_invoke_change - power cycle the device to implement the user
  *                         parameters
  * @indio_dev:	pointer to IIO device
  *
@@ -704,22 +723,22 @@ static int tsl2x7x_chip_off(struct iio_dev *indio_dev)
  * (On/Off), cycle device to implement updated parameter, put device back into
  * proper state, and unlock resource.
  */
-static int tsl2x7x_invoke_change(struct iio_dev *indio_dev)
+static int tsl2772_invoke_change(struct iio_dev *indio_dev)
 {
-	struct tsl2X7X_chip *chip = iio_priv(indio_dev);
-	int device_status = chip->tsl2x7x_chip_status;
+	struct tsl2772_chip *chip = iio_priv(indio_dev);
+	int device_status = chip->tsl2772_chip_status;
 	int ret;
 
 	mutex_lock(&chip->als_mutex);
 	mutex_lock(&chip->prox_mutex);
 
-	if (device_status == TSL2X7X_CHIP_WORKING) {
-		ret = tsl2x7x_chip_off(indio_dev);
+	if (device_status == TSL2772_CHIP_WORKING) {
+		ret = tsl2772_chip_off(indio_dev);
 		if (ret < 0)
 			goto unlock;
 	}
 
-	ret = tsl2x7x_chip_on(indio_dev);
+	ret = tsl2772_chip_on(indio_dev);
 
 unlock:
 	mutex_unlock(&chip->prox_mutex);
@@ -728,9 +747,9 @@ unlock:
 	return ret;
 }
 
-static int tsl2x7x_prox_cal(struct iio_dev *indio_dev)
+static int tsl2772_prox_cal(struct iio_dev *indio_dev)
 {
-	struct tsl2X7X_chip *chip = iio_priv(indio_dev);
+	struct tsl2772_chip *chip = iio_priv(indio_dev);
 	int prox_history[MAX_SAMPLES_CAL + 1];
 	int i, ret, mean, max, sample_sum;
 
@@ -740,7 +759,7 @@ static int tsl2x7x_prox_cal(struct iio_dev *indio_dev)
 
 	for (i = 0; i < chip->settings.prox_max_samples_cal; i++) {
 		usleep_range(15000, 17500);
-		ret = tsl2x7x_get_prox(indio_dev);
+		ret = tsl2772_get_prox(indio_dev);
 		if (ret < 0)
 			return ret;
 
@@ -757,21 +776,42 @@ static int tsl2x7x_prox_cal(struct iio_dev *indio_dev)
 
 	chip->settings.prox_thres_high = (max << 1) - mean;
 
-	return tsl2x7x_invoke_change(indio_dev);
+	return tsl2772_invoke_change(indio_dev);
 }
 
-static IIO_CONST_ATTR(in_intensity0_calibscale_available, "1 8 16 120");
+static int tsl2772_read_avail(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan,
+			      const int **vals, int *type, int *length,
+			      long mask)
+{
+	struct tsl2772_chip *chip = iio_priv(indio_dev);
 
-static IIO_CONST_ATTR(in_proximity0_calibscale_available, "1 2 4 8");
+	switch (mask) {
+	case IIO_CHAN_INFO_CALIBSCALE:
+		if (chan->type == IIO_INTENSITY) {
+			*length = ARRAY_SIZE(tsl2772_int_calibscale_avail);
+			*vals = tsl2772_int_calibscale_avail;
+		} else {
+			*length = ARRAY_SIZE(tsl2772_prox_calibscale_avail);
+			*vals = tsl2772_prox_calibscale_avail;
+		}
+		*type = IIO_VAL_INT;
+		return IIO_AVAIL_LIST;
+	case IIO_CHAN_INFO_INT_TIME:
+		*length = ARRAY_SIZE(tsl2772_int_time_avail[chip->id]);
+		*vals = tsl2772_int_time_avail[chip->id];
+		*type = IIO_VAL_INT_PLUS_MICRO;
+		return IIO_AVAIL_RANGE;
+	}
 
-static IIO_CONST_ATTR(in_intensity0_integration_time_available,
-		".00272 - .696");
+	return -EINVAL;
+}
 
 static ssize_t in_illuminance0_target_input_show(struct device *dev,
 						 struct device_attribute *attr,
 						 char *buf)
 {
-	struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev));
+	struct tsl2772_chip *chip = iio_priv(dev_to_iio_dev(dev));
 
 	return snprintf(buf, PAGE_SIZE, "%d\n", chip->settings.als_cal_target);
 }
@@ -781,7 +821,7 @@ static ssize_t in_illuminance0_target_input_store(struct device *dev,
 						  const char *buf, size_t len)
 {
 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct tsl2X7X_chip *chip = iio_priv(indio_dev);
+	struct tsl2772_chip *chip = iio_priv(indio_dev);
 	u16 value;
 	int ret;
 
@@ -789,7 +829,7 @@ static ssize_t in_illuminance0_target_input_store(struct device *dev,
 		return -EINVAL;
 
 	chip->settings.als_cal_target = value;
-	ret = tsl2x7x_invoke_change(indio_dev);
+	ret = tsl2772_invoke_change(indio_dev);
 	if (ret < 0)
 		return ret;
 
@@ -807,11 +847,11 @@ static ssize_t in_illuminance0_calibrate_store(struct device *dev,
 	if (kstrtobool(buf, &value) || !value)
 		return -EINVAL;
 
-	ret = tsl2x7x_als_calibrate(indio_dev);
+	ret = tsl2772_als_calibrate(indio_dev);
 	if (ret < 0)
 		return ret;
 
-	ret = tsl2x7x_invoke_change(indio_dev);
+	ret = tsl2772_invoke_change(indio_dev);
 	if (ret < 0)
 		return ret;
 
@@ -822,15 +862,15 @@ static ssize_t in_illuminance0_lux_table_show(struct device *dev,
 					      struct device_attribute *attr,
 					      char *buf)
 {
-	struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev));
+	struct tsl2772_chip *chip = iio_priv(dev_to_iio_dev(dev));
 	int i = 0;
 	int offset = 0;
 
-	while (i < TSL2X7X_MAX_LUX_TABLE_SIZE) {
+	while (i < TSL2772_MAX_LUX_TABLE_SIZE) {
 		offset += snprintf(buf + offset, PAGE_SIZE, "%u,%u,",
-			chip->tsl2x7x_device_lux[i].ch0,
-			chip->tsl2x7x_device_lux[i].ch1);
-		if (chip->tsl2x7x_device_lux[i].ch0 == 0) {
+			chip->tsl2772_device_lux[i].ch0,
+			chip->tsl2772_device_lux[i].ch1);
+		if (chip->tsl2772_device_lux[i].ch0 == 0) {
 			/*
 			 * We just printed the first "0" entry.
 			 * Now get rid of the extra "," and break.
@@ -850,8 +890,8 @@ static ssize_t in_illuminance0_lux_table_store(struct device *dev,
 					       const char *buf, size_t len)
 {
 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct tsl2X7X_chip *chip = iio_priv(indio_dev);
-	int value[ARRAY_SIZE(chip->tsl2x7x_device_lux) * 2 + 1];
+	struct tsl2772_chip *chip = iio_priv(indio_dev);
+	int value[ARRAY_SIZE(chip->tsl2772_device_lux) * 2 + 1];
 	int n, ret;
 
 	get_options(buf, ARRAY_SIZE(value), value);
@@ -864,23 +904,23 @@ static ssize_t in_illuminance0_lux_table_store(struct device *dev,
 	 */
 	n = value[0];
 	if ((n % 2) || n < 4 ||
-	    n > ((ARRAY_SIZE(chip->tsl2x7x_device_lux) - 1) * 2))
+	    n > ((ARRAY_SIZE(chip->tsl2772_device_lux) - 1) * 2))
 		return -EINVAL;
 
 	if ((value[(n - 1)] | value[n]) != 0)
 		return -EINVAL;
 
-	if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_WORKING) {
-		ret = tsl2x7x_chip_off(indio_dev);
+	if (chip->tsl2772_chip_status == TSL2772_CHIP_WORKING) {
+		ret = tsl2772_chip_off(indio_dev);
 		if (ret < 0)
 			return ret;
 	}
 
 	/* Zero out the table */
-	memset(chip->tsl2x7x_device_lux, 0, sizeof(chip->tsl2x7x_device_lux));
-	memcpy(chip->tsl2x7x_device_lux, &value[1], (value[0] * 4));
+	memset(chip->tsl2772_device_lux, 0, sizeof(chip->tsl2772_device_lux));
+	memcpy(chip->tsl2772_device_lux, &value[1], (value[0] * 4));
 
-	ret = tsl2x7x_invoke_change(indio_dev);
+	ret = tsl2772_invoke_change(indio_dev);
 	if (ret < 0)
 		return ret;
 
@@ -898,23 +938,23 @@ static ssize_t in_proximity0_calibrate_store(struct device *dev,
 	if (kstrtobool(buf, &value) || !value)
 		return -EINVAL;
 
-	ret = tsl2x7x_prox_cal(indio_dev);
+	ret = tsl2772_prox_cal(indio_dev);
 	if (ret < 0)
 		return ret;
 
-	ret = tsl2x7x_invoke_change(indio_dev);
+	ret = tsl2772_invoke_change(indio_dev);
 	if (ret < 0)
 		return ret;
 
 	return len;
 }
 
-static int tsl2x7x_read_interrupt_config(struct iio_dev *indio_dev,
+static int tsl2772_read_interrupt_config(struct iio_dev *indio_dev,
 					 const struct iio_chan_spec *chan,
 					 enum iio_event_type type,
 					 enum iio_event_direction dir)
 {
-	struct tsl2X7X_chip *chip = iio_priv(indio_dev);
+	struct tsl2772_chip *chip = iio_priv(indio_dev);
 
 	if (chan->type == IIO_INTENSITY)
 		return chip->settings.als_interrupt_en;
@@ -922,31 +962,31 @@ static int tsl2x7x_read_interrupt_config(struct iio_dev *indio_dev,
 		return chip->settings.prox_interrupt_en;
 }
 
-static int tsl2x7x_write_interrupt_config(struct iio_dev *indio_dev,
+static int tsl2772_write_interrupt_config(struct iio_dev *indio_dev,
 					  const struct iio_chan_spec *chan,
 					  enum iio_event_type type,
 					  enum iio_event_direction dir,
 					  int val)
 {
-	struct tsl2X7X_chip *chip = iio_priv(indio_dev);
+	struct tsl2772_chip *chip = iio_priv(indio_dev);
 
 	if (chan->type == IIO_INTENSITY)
 		chip->settings.als_interrupt_en = val ? true : false;
 	else
 		chip->settings.prox_interrupt_en = val ? true : false;
 
-	return tsl2x7x_invoke_change(indio_dev);
+	return tsl2772_invoke_change(indio_dev);
 }
 
-static int tsl2x7x_write_event_value(struct iio_dev *indio_dev,
+static int tsl2772_write_event_value(struct iio_dev *indio_dev,
 				     const struct iio_chan_spec *chan,
 				     enum iio_event_type type,
 				     enum iio_event_direction dir,
 				     enum iio_event_info info,
 				     int val, int val2)
 {
-	struct tsl2X7X_chip *chip = iio_priv(indio_dev);
-	int ret = -EINVAL, y, z, filter_delay;
+	struct tsl2772_chip *chip = iio_priv(indio_dev);
+	int ret = -EINVAL, count, persistence;
 	u8 time;
 
 	switch (info) {
@@ -985,15 +1025,20 @@ static int tsl2x7x_write_event_value(struct iio_dev *indio_dev,
 		else
 			time = chip->settings.prox_time;
 
-		y = (TSL2X7X_MAX_TIMER_CNT - time) + 1;
-		z = y * TSL2X7X_MIN_ITIME;
+		count = 256 - time;
+		persistence = ((val * 1000000) + val2) /
+			(count * tsl2772_int_time_avail[chip->id][3]);
+
+		if (chan->type == IIO_INTENSITY) {
+			/* ALS filter values are 1, 2, 3, 5, 10, 15, ..., 60 */
+			if (persistence > 3)
+				persistence = (persistence / 5) + 3;
 
-		filter_delay = DIV_ROUND_UP((val * 1000) + val2, z);
+			chip->settings.als_persistence = persistence;
+		} else {
+			chip->settings.prox_persistence = persistence;
+		}
 
-		if (chan->type == IIO_INTENSITY)
-			chip->settings.als_persistence = filter_delay;
-		else
-			chip->settings.prox_persistence = filter_delay;
 		ret = 0;
 		break;
 	default:
@@ -1003,18 +1048,18 @@ static int tsl2x7x_write_event_value(struct iio_dev *indio_dev,
 	if (ret < 0)
 		return ret;
 
-	return tsl2x7x_invoke_change(indio_dev);
+	return tsl2772_invoke_change(indio_dev);
 }
 
-static int tsl2x7x_read_event_value(struct iio_dev *indio_dev,
+static int tsl2772_read_event_value(struct iio_dev *indio_dev,
 				    const struct iio_chan_spec *chan,
 				    enum iio_event_type type,
 				    enum iio_event_direction dir,
 				    enum iio_event_info info,
 				    int *val, int *val2)
 {
-	struct tsl2X7X_chip *chip = iio_priv(indio_dev);
-	int ret = -EINVAL, filter_delay, mult;
+	struct tsl2772_chip *chip = iio_priv(indio_dev);
+	int filter_delay, persistence;
 	u8 time;
 
 	switch (info) {
@@ -1023,124 +1068,111 @@ static int tsl2x7x_read_event_value(struct iio_dev *indio_dev,
 			switch (dir) {
 			case IIO_EV_DIR_RISING:
 				*val = chip->settings.als_thresh_high;
-				ret = IIO_VAL_INT;
-				break;
+				return IIO_VAL_INT;
 			case IIO_EV_DIR_FALLING:
 				*val = chip->settings.als_thresh_low;
-				ret = IIO_VAL_INT;
-				break;
+				return IIO_VAL_INT;
 			default:
-				break;
+				return -EINVAL;
 			}
 		} else {
 			switch (dir) {
 			case IIO_EV_DIR_RISING:
 				*val = chip->settings.prox_thres_high;
-				ret = IIO_VAL_INT;
-				break;
+				return IIO_VAL_INT;
 			case IIO_EV_DIR_FALLING:
 				*val = chip->settings.prox_thres_low;
-				ret = IIO_VAL_INT;
-				break;
+				return IIO_VAL_INT;
 			default:
-				break;
+				return -EINVAL;
 			}
 		}
 		break;
 	case IIO_EV_INFO_PERIOD:
 		if (chan->type == IIO_INTENSITY) {
 			time = chip->settings.als_time;
-			mult = chip->settings.als_persistence;
+			persistence = chip->settings.als_persistence;
+
+			/* ALS filter values are 1, 2, 3, 5, 10, 15, ..., 60 */
+			if (persistence > 3)
+				persistence = (persistence - 3) * 5;
 		} else {
 			time = chip->settings.prox_time;
-			mult = chip->settings.prox_persistence;
+			persistence = chip->settings.prox_persistence;
 		}
 
-		/* Determine integration time */
-		*val = (TSL2X7X_MAX_TIMER_CNT - time) + 1;
-		*val2 = *val * TSL2X7X_MIN_ITIME;
-		filter_delay = *val2 * mult;
-		*val = filter_delay / 1000;
-		*val2 = filter_delay % 1000;
-		ret = IIO_VAL_INT_PLUS_MICRO;
-		break;
+		filter_delay = persistence * (256 - time) *
+			tsl2772_int_time_avail[chip->id][3];
+
+		*val = filter_delay / 1000000;
+		*val2 = filter_delay % 1000000;
+		return IIO_VAL_INT_PLUS_MICRO;
 	default:
-		break;
+		return -EINVAL;
 	}
-
-	return ret;
 }
 
-static int tsl2x7x_read_raw(struct iio_dev *indio_dev,
+static int tsl2772_read_raw(struct iio_dev *indio_dev,
 			    struct iio_chan_spec const *chan,
 			    int *val,
 			    int *val2,
 			    long mask)
 {
-	struct tsl2X7X_chip *chip = iio_priv(indio_dev);
-	int ret = -EINVAL;
+	struct tsl2772_chip *chip = iio_priv(indio_dev);
 
 	switch (mask) {
 	case IIO_CHAN_INFO_PROCESSED:
 		switch (chan->type) {
 		case IIO_LIGHT:
-			tsl2x7x_get_lux(indio_dev);
+			tsl2772_get_lux(indio_dev);
 			*val = chip->als_cur_info.lux;
-			ret = IIO_VAL_INT;
-			break;
+			return IIO_VAL_INT;
 		default:
 			return -EINVAL;
 		}
-		break;
 	case IIO_CHAN_INFO_RAW:
 		switch (chan->type) {
 		case IIO_INTENSITY:
-			tsl2x7x_get_lux(indio_dev);
+			tsl2772_get_lux(indio_dev);
 			if (chan->channel == 0)
 				*val = chip->als_cur_info.als_ch0;
 			else
 				*val = chip->als_cur_info.als_ch1;
-			ret = IIO_VAL_INT;
-			break;
+			return IIO_VAL_INT;
 		case IIO_PROXIMITY:
-			tsl2x7x_get_prox(indio_dev);
+			tsl2772_get_prox(indio_dev);
 			*val = chip->prox_data;
-			ret = IIO_VAL_INT;
-			break;
+			return IIO_VAL_INT;
 		default:
 			return -EINVAL;
 		}
 		break;
 	case IIO_CHAN_INFO_CALIBSCALE:
 		if (chan->type == IIO_LIGHT)
-			*val = tsl2x7x_als_gain[chip->settings.als_gain];
+			*val = tsl2772_als_gain[chip->settings.als_gain];
 		else
-			*val = tsl2x7x_prox_gain[chip->settings.prox_gain];
-		ret = IIO_VAL_INT;
-		break;
+			*val = tsl2772_prox_gain[chip->settings.prox_gain];
+		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_CALIBBIAS:
 		*val = chip->settings.als_gain_trim;
-		ret = IIO_VAL_INT;
-		break;
+		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_INT_TIME:
 		*val = 0;
-		*val2 = (256 - chip->settings.als_time) * 2720;
-		ret = IIO_VAL_INT_PLUS_MICRO;
-		break;
+		*val2 = (256 - chip->settings.als_time) *
+			tsl2772_int_time_avail[chip->id][3];
+		return IIO_VAL_INT_PLUS_MICRO;
 	default:
-		ret = -EINVAL;
+		return -EINVAL;
 	}
-
-	return ret;
 }
 
-static int tsl2x7x_write_raw(struct iio_dev *indio_dev,
+static int tsl2772_write_raw(struct iio_dev *indio_dev,
 			     struct iio_chan_spec const *chan,
 			     int val,
 			     int val2,
 			     long mask)
 {
-	struct tsl2X7X_chip *chip = iio_priv(indio_dev);
+	struct tsl2772_chip *chip = iio_priv(indio_dev);
 
 	switch (mask) {
 	case IIO_CHAN_INFO_CALIBSCALE:
@@ -1181,16 +1213,25 @@ static int tsl2x7x_write_raw(struct iio_dev *indio_dev,
 		}
 		break;
 	case IIO_CHAN_INFO_CALIBBIAS:
+		if (val < TSL2772_ALS_GAIN_TRIM_MIN ||
+		    val > TSL2772_ALS_GAIN_TRIM_MAX)
+			return -EINVAL;
+
 		chip->settings.als_gain_trim = val;
 		break;
 	case IIO_CHAN_INFO_INT_TIME:
-		chip->settings.als_time = 256 - (val2 / 2720);
+		if (val != 0 || val2 < tsl2772_int_time_avail[chip->id][1] ||
+		    val2 > tsl2772_int_time_avail[chip->id][5])
+			return -EINVAL;
+
+		chip->settings.als_time = 256 -
+			(val2 / tsl2772_int_time_avail[chip->id][3]);
 		break;
 	default:
 		return -EINVAL;
 	}
 
-	return tsl2x7x_invoke_change(indio_dev);
+	return tsl2772_invoke_change(indio_dev);
 }
 
 static DEVICE_ATTR_RW(in_illuminance0_target_input);
@@ -1202,7 +1243,7 @@ static DEVICE_ATTR_WO(in_proximity0_calibrate);
 static DEVICE_ATTR_RW(in_illuminance0_lux_table);
 
 /* Use the default register values to identify the Taos device */
-static int tsl2x7x_device_id_verif(int id, int target)
+static int tsl2772_device_id_verif(int id, int target)
 {
 	switch (target) {
 	case tsl2571:
@@ -1223,28 +1264,28 @@ static int tsl2x7x_device_id_verif(int id, int target)
 	return -EINVAL;
 }
 
-static irqreturn_t tsl2x7x_event_handler(int irq, void *private)
+static irqreturn_t tsl2772_event_handler(int irq, void *private)
 {
 	struct iio_dev *indio_dev = private;
-	struct tsl2X7X_chip *chip = iio_priv(indio_dev);
+	struct tsl2772_chip *chip = iio_priv(indio_dev);
 	s64 timestamp = iio_get_time_ns(indio_dev);
 	int ret;
 
-	ret = tsl2x7x_read_status(chip);
+	ret = tsl2772_read_status(chip);
 	if (ret < 0)
 		return IRQ_HANDLED;
 
 	/* What type of interrupt do we need to process */
-	if (ret & TSL2X7X_STA_PRX_INTR) {
+	if (ret & TSL2772_STA_PRX_INTR) {
 		iio_push_event(indio_dev,
 			       IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY,
 						    0,
 						    IIO_EV_TYPE_THRESH,
 						    IIO_EV_DIR_EITHER),
-						    timestamp);
+			       timestamp);
 	}
 
-	if (ret & TSL2X7X_STA_ALS_INTR) {
+	if (ret & TSL2772_STA_ALS_INTR) {
 		iio_push_event(indio_dev,
 			       IIO_UNMOD_EVENT_CODE(IIO_LIGHT,
 						    0,
@@ -1254,8 +1295,8 @@ static irqreturn_t tsl2x7x_event_handler(int irq, void *private)
 	}
 
 	ret = i2c_smbus_write_byte(chip->client,
-				   TSL2X7X_CMD_REG | TSL2X7X_CMD_SPL_FN |
-				   TSL2X7X_CMD_PROXALS_INT_CLR);
+				   TSL2772_CMD_REG | TSL2772_CMD_SPL_FN |
+				   TSL2772_CMD_PROXALS_INT_CLR);
 	if (ret < 0)
 		dev_err(&chip->client->dev,
 			"%s: failed to clear interrupt status: %d\n",
@@ -1264,113 +1305,77 @@ static irqreturn_t tsl2x7x_event_handler(int irq, void *private)
 	return IRQ_HANDLED;
 }
 
-static struct attribute *tsl2x7x_ALS_device_attrs[] = {
-	&iio_const_attr_in_intensity0_calibscale_available.dev_attr.attr,
-	&iio_const_attr_in_intensity0_integration_time_available.dev_attr.attr,
+static struct attribute *tsl2772_ALS_device_attrs[] = {
 	&dev_attr_in_illuminance0_target_input.attr,
 	&dev_attr_in_illuminance0_calibrate.attr,
 	&dev_attr_in_illuminance0_lux_table.attr,
 	NULL
 };
 
-static struct attribute *tsl2x7x_PRX_device_attrs[] = {
+static struct attribute *tsl2772_PRX_device_attrs[] = {
 	&dev_attr_in_proximity0_calibrate.attr,
 	NULL
 };
 
-static struct attribute *tsl2x7x_ALSPRX_device_attrs[] = {
-	&iio_const_attr_in_intensity0_calibscale_available.dev_attr.attr,
-	&iio_const_attr_in_intensity0_integration_time_available.dev_attr.attr,
+static struct attribute *tsl2772_ALSPRX_device_attrs[] = {
 	&dev_attr_in_illuminance0_target_input.attr,
 	&dev_attr_in_illuminance0_calibrate.attr,
 	&dev_attr_in_illuminance0_lux_table.attr,
 	NULL
 };
 
-static struct attribute *tsl2x7x_PRX2_device_attrs[] = {
+static struct attribute *tsl2772_PRX2_device_attrs[] = {
 	&dev_attr_in_proximity0_calibrate.attr,
-	&iio_const_attr_in_proximity0_calibscale_available.dev_attr.attr,
 	NULL
 };
 
-static struct attribute *tsl2x7x_ALSPRX2_device_attrs[] = {
-	&iio_const_attr_in_intensity0_calibscale_available.dev_attr.attr,
-	&iio_const_attr_in_intensity0_integration_time_available.dev_attr.attr,
+static struct attribute *tsl2772_ALSPRX2_device_attrs[] = {
 	&dev_attr_in_illuminance0_target_input.attr,
 	&dev_attr_in_illuminance0_calibrate.attr,
 	&dev_attr_in_illuminance0_lux_table.attr,
 	&dev_attr_in_proximity0_calibrate.attr,
-	&iio_const_attr_in_proximity0_calibscale_available.dev_attr.attr,
 	NULL
 };
 
-static const struct attribute_group tsl2X7X_device_attr_group_tbl[] = {
+static const struct attribute_group tsl2772_device_attr_group_tbl[] = {
 	[ALS] = {
-		.attrs = tsl2x7x_ALS_device_attrs,
+		.attrs = tsl2772_ALS_device_attrs,
 	},
 	[PRX] = {
-		.attrs = tsl2x7x_PRX_device_attrs,
+		.attrs = tsl2772_PRX_device_attrs,
 	},
 	[ALSPRX] = {
-		.attrs = tsl2x7x_ALSPRX_device_attrs,
+		.attrs = tsl2772_ALSPRX_device_attrs,
 	},
 	[PRX2] = {
-		.attrs = tsl2x7x_PRX2_device_attrs,
+		.attrs = tsl2772_PRX2_device_attrs,
 	},
 	[ALSPRX2] = {
-		.attrs = tsl2x7x_ALSPRX2_device_attrs,
+		.attrs = tsl2772_ALSPRX2_device_attrs,
 	},
 };
 
-static const struct iio_info tsl2X7X_device_info[] = {
-	[ALS] = {
-		.attrs = &tsl2X7X_device_attr_group_tbl[ALS],
-		.read_raw = &tsl2x7x_read_raw,
-		.write_raw = &tsl2x7x_write_raw,
-		.read_event_value = &tsl2x7x_read_event_value,
-		.write_event_value = &tsl2x7x_write_event_value,
-		.read_event_config = &tsl2x7x_read_interrupt_config,
-		.write_event_config = &tsl2x7x_write_interrupt_config,
-	},
-	[PRX] = {
-		.attrs = &tsl2X7X_device_attr_group_tbl[PRX],
-		.read_raw = &tsl2x7x_read_raw,
-		.write_raw = &tsl2x7x_write_raw,
-		.read_event_value = &tsl2x7x_read_event_value,
-		.write_event_value = &tsl2x7x_write_event_value,
-		.read_event_config = &tsl2x7x_read_interrupt_config,
-		.write_event_config = &tsl2x7x_write_interrupt_config,
-	},
-	[ALSPRX] = {
-		.attrs = &tsl2X7X_device_attr_group_tbl[ALSPRX],
-		.read_raw = &tsl2x7x_read_raw,
-		.write_raw = &tsl2x7x_write_raw,
-		.read_event_value = &tsl2x7x_read_event_value,
-		.write_event_value = &tsl2x7x_write_event_value,
-		.read_event_config = &tsl2x7x_read_interrupt_config,
-		.write_event_config = &tsl2x7x_write_interrupt_config,
-	},
-	[PRX2] = {
-		.attrs = &tsl2X7X_device_attr_group_tbl[PRX2],
-		.read_raw = &tsl2x7x_read_raw,
-		.write_raw = &tsl2x7x_write_raw,
-		.read_event_value = &tsl2x7x_read_event_value,
-		.write_event_value = &tsl2x7x_write_event_value,
-		.read_event_config = &tsl2x7x_read_interrupt_config,
-		.write_event_config = &tsl2x7x_write_interrupt_config,
-	},
-	[ALSPRX2] = {
-		.attrs = &tsl2X7X_device_attr_group_tbl[ALSPRX2],
-		.read_raw = &tsl2x7x_read_raw,
-		.write_raw = &tsl2x7x_write_raw,
-		.read_event_value = &tsl2x7x_read_event_value,
-		.write_event_value = &tsl2x7x_write_event_value,
-		.read_event_config = &tsl2x7x_read_interrupt_config,
-		.write_event_config = &tsl2x7x_write_interrupt_config,
-	},
+#define TSL2772_DEVICE_INFO(type)[type] = \
+	{ \
+		.attrs = &tsl2772_device_attr_group_tbl[type], \
+		.read_raw = &tsl2772_read_raw, \
+		.read_avail = &tsl2772_read_avail, \
+		.write_raw = &tsl2772_write_raw, \
+		.read_event_value = &tsl2772_read_event_value, \
+		.write_event_value = &tsl2772_write_event_value, \
+		.read_event_config = &tsl2772_read_interrupt_config, \
+		.write_event_config = &tsl2772_write_interrupt_config, \
+	}
+
+static const struct iio_info tsl2772_device_info[] = {
+	TSL2772_DEVICE_INFO(ALS),
+	TSL2772_DEVICE_INFO(PRX),
+	TSL2772_DEVICE_INFO(ALSPRX),
+	TSL2772_DEVICE_INFO(PRX2),
+	TSL2772_DEVICE_INFO(ALSPRX2),
 };
 
-static const struct iio_event_spec tsl2x7x_events[] = {
+static const struct iio_event_spec tsl2772_events[] = {
 	{
 		.type = IIO_EV_TYPE_THRESH,
 		.dir = IIO_EV_DIR_RISING,
@@ -1387,7 +1392,7 @@ static const struct iio_event_spec tsl2x7x_events[] = {
 	},
 };
 
-static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
+static const struct tsl2772_chip_info tsl2772_chip_info_tbl[] = {
 	[ALS] = {
 		.channel_with_events = {
 			{
@@ -1403,8 +1408,11 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
 				BIT(IIO_CHAN_INFO_INT_TIME) |
 				BIT(IIO_CHAN_INFO_CALIBSCALE) |
 				BIT(IIO_CHAN_INFO_CALIBBIAS),
-			.event_spec = tsl2x7x_events,
-			.num_event_specs = ARRAY_SIZE(tsl2x7x_events),
+			.info_mask_separate_available =
+				BIT(IIO_CHAN_INFO_INT_TIME) |
+				BIT(IIO_CHAN_INFO_CALIBSCALE),
+			.event_spec = tsl2772_events,
+			.num_event_specs = ARRAY_SIZE(tsl2772_events),
 			}, {
 			.type = IIO_INTENSITY,
 			.indexed = 1,
@@ -1425,6 +1433,9 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
 				BIT(IIO_CHAN_INFO_INT_TIME) |
 				BIT(IIO_CHAN_INFO_CALIBSCALE) |
 				BIT(IIO_CHAN_INFO_CALIBBIAS),
+			.info_mask_separate_available =
+				BIT(IIO_CHAN_INFO_INT_TIME) |
+				BIT(IIO_CHAN_INFO_CALIBSCALE),
 			}, {
 			.type = IIO_INTENSITY,
 			.indexed = 1,
@@ -1432,7 +1443,7 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
 			},
 		},
 		.chan_table_elements = 3,
-		.info = &tsl2X7X_device_info[ALS],
+		.info = &tsl2772_device_info[ALS],
 	},
 	[PRX] = {
 		.channel_with_events = {
@@ -1441,8 +1452,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
 			.indexed = 1,
 			.channel = 0,
 			.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
-			.event_spec = tsl2x7x_events,
-			.num_event_specs = ARRAY_SIZE(tsl2x7x_events),
+			.event_spec = tsl2772_events,
+			.num_event_specs = ARRAY_SIZE(tsl2772_events),
 			},
 		},
 		.channel_without_events = {
@@ -1454,7 +1465,7 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
 			},
 		},
 		.chan_table_elements = 1,
-		.info = &tsl2X7X_device_info[PRX],
+		.info = &tsl2772_device_info[PRX],
 	},
 	[ALSPRX] = {
 		.channel_with_events = {
@@ -1471,8 +1482,11 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
 				BIT(IIO_CHAN_INFO_INT_TIME) |
 				BIT(IIO_CHAN_INFO_CALIBSCALE) |
 				BIT(IIO_CHAN_INFO_CALIBBIAS),
-			.event_spec = tsl2x7x_events,
-			.num_event_specs = ARRAY_SIZE(tsl2x7x_events),
+			.info_mask_separate_available =
+				BIT(IIO_CHAN_INFO_INT_TIME) |
+				BIT(IIO_CHAN_INFO_CALIBSCALE),
+			.event_spec = tsl2772_events,
+			.num_event_specs = ARRAY_SIZE(tsl2772_events),
 			}, {
 			.type = IIO_INTENSITY,
 			.indexed = 1,
@@ -1483,8 +1497,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
 			.indexed = 1,
 			.channel = 0,
 			.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
-			.event_spec = tsl2x7x_events,
-			.num_event_specs = ARRAY_SIZE(tsl2x7x_events),
+			.event_spec = tsl2772_events,
+			.num_event_specs = ARRAY_SIZE(tsl2772_events),
 			},
 		},
 		.channel_without_events = {
@@ -1501,6 +1515,9 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
 				BIT(IIO_CHAN_INFO_INT_TIME) |
 				BIT(IIO_CHAN_INFO_CALIBSCALE) |
 				BIT(IIO_CHAN_INFO_CALIBBIAS),
+			.info_mask_separate_available =
+				BIT(IIO_CHAN_INFO_INT_TIME) |
+				BIT(IIO_CHAN_INFO_CALIBSCALE),
 			}, {
 			.type = IIO_INTENSITY,
 			.indexed = 1,
@@ -1514,7 +1531,7 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
 			},
 		},
 		.chan_table_elements = 4,
-		.info = &tsl2X7X_device_info[ALSPRX],
+		.info = &tsl2772_device_info[ALSPRX],
 	},
 	[PRX2] = {
 		.channel_with_events = {
@@ -1524,8 +1541,10 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
 			.channel = 0,
 			.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 				BIT(IIO_CHAN_INFO_CALIBSCALE),
-			.event_spec = tsl2x7x_events,
-			.num_event_specs = ARRAY_SIZE(tsl2x7x_events),
+			.info_mask_separate_available =
+				BIT(IIO_CHAN_INFO_CALIBSCALE),
+			.event_spec = tsl2772_events,
+			.num_event_specs = ARRAY_SIZE(tsl2772_events),
 			},
 		},
 		.channel_without_events = {
@@ -1535,10 +1554,12 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
 			.channel = 0,
 			.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 				BIT(IIO_CHAN_INFO_CALIBSCALE),
+			.info_mask_separate_available =
+				BIT(IIO_CHAN_INFO_CALIBSCALE),
 			},
 		},
 		.chan_table_elements = 1,
-		.info = &tsl2X7X_device_info[PRX2],
+		.info = &tsl2772_device_info[PRX2],
 	},
 	[ALSPRX2] = {
 		.channel_with_events = {
@@ -1555,8 +1576,11 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
 				BIT(IIO_CHAN_INFO_INT_TIME) |
 				BIT(IIO_CHAN_INFO_CALIBSCALE) |
 				BIT(IIO_CHAN_INFO_CALIBBIAS),
-			.event_spec = tsl2x7x_events,
-			.num_event_specs = ARRAY_SIZE(tsl2x7x_events),
+			.info_mask_separate_available =
+				BIT(IIO_CHAN_INFO_INT_TIME) |
+				BIT(IIO_CHAN_INFO_CALIBSCALE),
+			.event_spec = tsl2772_events,
+			.num_event_specs = ARRAY_SIZE(tsl2772_events),
 			}, {
 			.type = IIO_INTENSITY,
 			.indexed = 1,
@@ -1568,8 +1592,10 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
 			.channel = 0,
 			.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 				BIT(IIO_CHAN_INFO_CALIBSCALE),
-			.event_spec = tsl2x7x_events,
-			.num_event_specs = ARRAY_SIZE(tsl2x7x_events),
+			.info_mask_separate_available =
+				BIT(IIO_CHAN_INFO_CALIBSCALE),
+			.event_spec = tsl2772_events,
+			.num_event_specs = ARRAY_SIZE(tsl2772_events),
 			},
 		},
 		.channel_without_events = {
@@ -1586,6 +1612,9 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
 				BIT(IIO_CHAN_INFO_INT_TIME) |
 				BIT(IIO_CHAN_INFO_CALIBSCALE) |
 				BIT(IIO_CHAN_INFO_CALIBBIAS),
+			.info_mask_separate_available =
+				BIT(IIO_CHAN_INFO_INT_TIME) |
+				BIT(IIO_CHAN_INFO_CALIBSCALE),
 			}, {
 			.type = IIO_INTENSITY,
 			.indexed = 1,
@@ -1597,18 +1626,20 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
 			.channel = 0,
 			.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 				BIT(IIO_CHAN_INFO_CALIBSCALE),
+			.info_mask_separate_available =
+				BIT(IIO_CHAN_INFO_CALIBSCALE),
 			},
 		},
 		.chan_table_elements = 4,
-		.info = &tsl2X7X_device_info[ALSPRX2],
+		.info = &tsl2772_device_info[ALSPRX2],
 	},
 };
 
-static int tsl2x7x_probe(struct i2c_client *clientp,
+static int tsl2772_probe(struct i2c_client *clientp,
 			 const struct i2c_device_id *id)
 {
 	struct iio_dev *indio_dev;
-	struct tsl2X7X_chip *chip;
+	struct tsl2772_chip *chip;
 	int ret;
 
 	indio_dev = devm_iio_device_alloc(&clientp->dev, sizeof(*chip));
@@ -1620,18 +1651,18 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
 	i2c_set_clientdata(clientp, indio_dev);
 
 	ret = i2c_smbus_read_byte_data(chip->client,
-				       TSL2X7X_CMD_REG | TSL2X7X_CHIPID);
+				       TSL2772_CMD_REG | TSL2772_CHIPID);
 	if (ret < 0)
 		return ret;
 
-	if (tsl2x7x_device_id_verif(ret, id->driver_data) <= 0) {
+	if (tsl2772_device_id_verif(ret, id->driver_data) <= 0) {
 		dev_info(&chip->client->dev,
 			 "%s: i2c device found does not match expected id\n",
 				__func__);
 		return -EINVAL;
 	}
 
-	ret = i2c_smbus_write_byte(clientp, TSL2X7X_CMD_REG | TSL2X7X_CNTRL);
+	ret = i2c_smbus_write_byte(clientp, TSL2772_CMD_REG | TSL2772_CNTRL);
 	if (ret < 0) {
 		dev_err(&clientp->dev,
 			"%s: Failed to write to CMD register: %d\n",
@@ -1642,11 +1673,11 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
 	mutex_init(&chip->als_mutex);
 	mutex_init(&chip->prox_mutex);
 
-	chip->tsl2x7x_chip_status = TSL2X7X_CHIP_UNKNOWN;
+	chip->tsl2772_chip_status = TSL2772_CHIP_UNKNOWN;
 	chip->pdata = dev_get_platdata(&clientp->dev);
 	chip->id = id->driver_data;
 	chip->chip_info =
-		&tsl2x7x_chip_info_tbl[device_channel_config[id->driver_data]];
+		&tsl2772_chip_info_tbl[device_channel_config[id->driver_data]];
 
 	indio_dev->info = chip->chip_info->info;
 	indio_dev->dev.parent = &clientp->dev;
@@ -1659,10 +1690,10 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
 
 		ret = devm_request_threaded_irq(&clientp->dev, clientp->irq,
 						NULL,
-						&tsl2x7x_event_handler,
+						&tsl2772_event_handler,
 						IRQF_TRIGGER_FALLING |
 						IRQF_ONESHOT,
-						"TSL2X7X_event",
+						"TSL2772_event",
 						indio_dev);
 		if (ret) {
 			dev_err(&clientp->dev,
@@ -1673,11 +1704,14 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
 		indio_dev->channels = chip->chip_info->channel_without_events;
 	}
 
-	tsl2x7x_defaults(chip);
-	tsl2x7x_chip_on(indio_dev);
+	tsl2772_defaults(chip);
+	ret = tsl2772_chip_on(indio_dev);
+	if (ret < 0)
+		return ret;
 
 	ret = iio_device_register(indio_dev);
 	if (ret) {
+		tsl2772_chip_off(indio_dev);
 		dev_err(&clientp->dev,
 			"%s: iio registration failed\n", __func__);
 		return ret;
@@ -1686,32 +1720,32 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
 	return 0;
 }
 
-static int tsl2x7x_suspend(struct device *dev)
+static int tsl2772_suspend(struct device *dev)
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 
-	return tsl2x7x_chip_off(indio_dev);
+	return tsl2772_chip_off(indio_dev);
 }
 
-static int tsl2x7x_resume(struct device *dev)
+static int tsl2772_resume(struct device *dev)
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 
-	return tsl2x7x_chip_on(indio_dev);
+	return tsl2772_chip_on(indio_dev);
 }
 
-static int tsl2x7x_remove(struct i2c_client *client)
+static int tsl2772_remove(struct i2c_client *client)
 {
 	struct iio_dev *indio_dev = i2c_get_clientdata(client);
 
-	tsl2x7x_chip_off(indio_dev);
+	tsl2772_chip_off(indio_dev);
 
 	iio_device_unregister(indio_dev);
 
 	return 0;
 }
 
-static const struct i2c_device_id tsl2x7x_idtable[] = {
+static const struct i2c_device_id tsl2772_idtable[] = {
 	{ "tsl2571", tsl2571 },
 	{ "tsl2671", tsl2671 },
 	{ "tmd2671", tmd2671 },
@@ -1725,9 +1759,9 @@ static const struct i2c_device_id tsl2x7x_idtable[] = {
 	{}
 };
 
-MODULE_DEVICE_TABLE(i2c, tsl2x7x_idtable);
+MODULE_DEVICE_TABLE(i2c, tsl2772_idtable);
 
-static const struct of_device_id tsl2x7x_of_match[] = {
+static const struct of_device_id tsl2772_of_match[] = {
 	{ .compatible = "amstaos,tsl2571" },
 	{ .compatible = "amstaos,tsl2671" },
 	{ .compatible = "amstaos,tmd2671" },
@@ -1740,27 +1774,27 @@ static const struct of_device_id tsl2x7x_of_match[] = {
 	{ .compatible = "amstaos,tmd2772" },
 	{}
 };
-MODULE_DEVICE_TABLE(of, tsl2x7x_of_match);
+MODULE_DEVICE_TABLE(of, tsl2772_of_match);
 
-static const struct dev_pm_ops tsl2x7x_pm_ops = {
-	.suspend = tsl2x7x_suspend,
-	.resume  = tsl2x7x_resume,
+static const struct dev_pm_ops tsl2772_pm_ops = {
+	.suspend = tsl2772_suspend,
+	.resume  = tsl2772_resume,
 };
 
-static struct i2c_driver tsl2x7x_driver = {
+static struct i2c_driver tsl2772_driver = {
 	.driver = {
-		.name = "tsl2x7x",
-		.of_match_table = tsl2x7x_of_match,
-		.pm = &tsl2x7x_pm_ops,
+		.name = "tsl2772",
+		.of_match_table = tsl2772_of_match,
+		.pm = &tsl2772_pm_ops,
 	},
-	.id_table = tsl2x7x_idtable,
-	.probe = tsl2x7x_probe,
-	.remove = tsl2x7x_remove,
+	.id_table = tsl2772_idtable,
+	.probe = tsl2772_probe,
+	.remove = tsl2772_remove,
 };
 
-module_i2c_driver(tsl2x7x_driver);
+module_i2c_driver(tsl2772_driver);
 
 MODULE_AUTHOR("J. August Brenner <Jon.Brenner@ams.com>");
 MODULE_AUTHOR("Brian Masney <masneyb@onstation.org>");
-MODULE_DESCRIPTION("TAOS tsl2x7x ambient and proximity light sensor driver");
+MODULE_DESCRIPTION("TAOS tsl2772 ambient and proximity light sensor driver");
 MODULE_LICENSE("GPL");

+ 140 - 18
drivers/iio/magnetometer/mag3110.c

@@ -26,6 +26,7 @@
 #define MAG3110_OUT_Y 0x03
 #define MAG3110_OUT_Z 0x05
 #define MAG3110_WHO_AM_I 0x07
+#define MAG3110_SYSMOD 0x08
 #define MAG3110_OFF_X 0x09 /* MSB first */
 #define MAG3110_OFF_Y 0x0b
 #define MAG3110_OFF_Z 0x0d
@@ -39,6 +40,8 @@
 #define MAG3110_CTRL_DR_SHIFT 5
 #define MAG3110_CTRL_DR_DEFAULT 0
 
+#define MAG3110_SYSMOD_MODE_MASK GENMASK(1, 0)
+
 #define MAG3110_CTRL_TM BIT(1) /* trigger single measurement */
 #define MAG3110_CTRL_AC BIT(0) /* continuous measurements */
 
@@ -52,17 +55,20 @@ struct mag3110_data {
 	struct i2c_client *client;
 	struct mutex lock;
 	u8 ctrl_reg1;
+	int sleep_val;
 };
 
 static int mag3110_request(struct mag3110_data *data)
 {
 	int ret, tries = 150;
 
-	/* trigger measurement */
-	ret = i2c_smbus_write_byte_data(data->client, MAG3110_CTRL_REG1,
-		data->ctrl_reg1 | MAG3110_CTRL_TM);
-	if (ret < 0)
-		return ret;
+	if ((data->ctrl_reg1 & MAG3110_CTRL_AC) == 0) {
+		/* trigger measurement */
+		ret = i2c_smbus_write_byte_data(data->client, MAG3110_CTRL_REG1,
+			data->ctrl_reg1 | MAG3110_CTRL_TM);
+		if (ret < 0)
+			return ret;
+	}
 
 	while (tries-- > 0) {
 		ret = i2c_smbus_read_byte_data(data->client, MAG3110_STATUS);
@@ -71,7 +77,11 @@ static int mag3110_request(struct mag3110_data *data)
 		/* wait for data ready */
 		if ((ret & MAG3110_STATUS_DRDY) == MAG3110_STATUS_DRDY)
 			break;
-		msleep(20);
+
+		if (data->sleep_val <= 20)
+			usleep_range(data->sleep_val * 250, data->sleep_val * 500);
+		else
+			msleep(20);
 	}
 
 	if (tries < 0) {
@@ -144,6 +154,117 @@ static int mag3110_get_samp_freq_index(struct mag3110_data *data,
 		val2);
 }
 
+static int mag3110_calculate_sleep(struct mag3110_data *data)
+{
+	int ret, i = data->ctrl_reg1 >> MAG3110_CTRL_DR_SHIFT;
+
+	if (mag3110_samp_freq[i][0] > 0)
+		ret = 1000 / mag3110_samp_freq[i][0];
+	else
+		ret = 1000;
+
+	return ret == 0 ? 1 : ret;
+}
+
+static int mag3110_standby(struct mag3110_data *data)
+{
+	return i2c_smbus_write_byte_data(data->client, MAG3110_CTRL_REG1,
+		data->ctrl_reg1 & ~MAG3110_CTRL_AC);
+}
+
+static int mag3110_wait_standby(struct mag3110_data *data)
+{
+	int ret, tries = 30;
+
+	/*
+	 * Takes up to 1/ODR to come out of active mode into stby
+	 * Longest expected period is 12.5seconds.
+	 * We'll sleep for 500ms between checks
+	 */
+	while (tries-- > 0) {
+		ret = i2c_smbus_read_byte_data(data->client, MAG3110_SYSMOD);
+		if (ret < 0) {
+			dev_err(&data->client->dev, "i2c error\n");
+			return ret;
+		}
+		/* wait for standby */
+		if ((ret & MAG3110_SYSMOD_MODE_MASK) == 0)
+			break;
+
+		msleep_interruptible(500);
+	}
+
+	if (tries < 0) {
+		dev_err(&data->client->dev, "device not entering standby mode\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int mag3110_active(struct mag3110_data *data)
+{
+	return i2c_smbus_write_byte_data(data->client, MAG3110_CTRL_REG1,
+					 data->ctrl_reg1);
+}
+
+/* returns >0 if active, 0 if in standby and <0 on error */
+static int mag3110_is_active(struct mag3110_data *data)
+{
+	int reg;
+
+	reg = i2c_smbus_read_byte_data(data->client, MAG3110_CTRL_REG1);
+	if (reg < 0)
+		return reg;
+
+	return reg & MAG3110_CTRL_AC;
+}
+
+static int mag3110_change_config(struct mag3110_data *data, u8 reg, u8 val)
+{
+	int ret;
+	int is_active;
+
+	mutex_lock(&data->lock);
+
+	is_active = mag3110_is_active(data);
+	if (is_active < 0) {
+		ret = is_active;
+		goto fail;
+	}
+
+	/* config can only be changed when in standby */
+	if (is_active > 0) {
+		ret = mag3110_standby(data);
+		if (ret < 0)
+			goto fail;
+	}
+
+	/*
+	 * After coming out of active we must wait for the part
+	 * to transition to STBY. This can take up to 1 /ODR to occur
+	 */
+	ret = mag3110_wait_standby(data);
+	if (ret < 0)
+		goto fail;
+
+	ret = i2c_smbus_write_byte_data(data->client, reg, val);
+	if (ret < 0)
+		goto fail;
+
+	if (is_active > 0) {
+		ret = mag3110_active(data);
+		if (ret < 0)
+			goto fail;
+	}
+
+	ret = 0;
+fail:
+	mutex_unlock(&data->lock);
+
+	return ret;
+}
+
 static int mag3110_read_raw(struct iio_dev *indio_dev,
 			    struct iio_chan_spec const *chan,
 			    int *val, int *val2, long mask)
@@ -235,11 +356,15 @@ static int mag3110_write_raw(struct iio_dev *indio_dev,
 			ret = -EINVAL;
 			break;
 		}
-
-		data->ctrl_reg1 &= ~MAG3110_CTRL_DR_MASK;
+		data->ctrl_reg1 &= 0xff & ~MAG3110_CTRL_DR_MASK
+					& ~MAG3110_CTRL_AC;
 		data->ctrl_reg1 |= rate << MAG3110_CTRL_DR_SHIFT;
-		ret = i2c_smbus_write_byte_data(data->client,
-			MAG3110_CTRL_REG1, data->ctrl_reg1);
+		data->sleep_val = mag3110_calculate_sleep(data);
+		if (data->sleep_val < 40)
+			data->ctrl_reg1 |= MAG3110_CTRL_AC;
+
+		ret = mag3110_change_config(data, MAG3110_CTRL_REG1,
+					    data->ctrl_reg1);
 		break;
 	case IIO_CHAN_INFO_CALIBBIAS:
 		if (val < -10000 || val > 10000) {
@@ -337,12 +462,6 @@ static const struct iio_info mag3110_info = {
 
 static const unsigned long mag3110_scan_masks[] = {0x7, 0xf, 0};
 
-static int mag3110_standby(struct mag3110_data *data)
-{
-	return i2c_smbus_write_byte_data(data->client, MAG3110_CTRL_REG1,
-		data->ctrl_reg1 & ~MAG3110_CTRL_AC);
-}
-
 static int mag3110_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 {
@@ -374,8 +493,11 @@ static int mag3110_probe(struct i2c_client *client,
 	indio_dev->available_scan_masks = mag3110_scan_masks;
 
 	data->ctrl_reg1 = MAG3110_CTRL_DR_DEFAULT << MAG3110_CTRL_DR_SHIFT;
-	ret = i2c_smbus_write_byte_data(client, MAG3110_CTRL_REG1,
-		data->ctrl_reg1);
+	data->sleep_val = mag3110_calculate_sleep(data);
+	if (data->sleep_val < 40)
+		data->ctrl_reg1 |= MAG3110_CTRL_AC;
+
+	ret = mag3110_change_config(data, MAG3110_CTRL_REG1, data->ctrl_reg1);
 	if (ret < 0)
 		return ret;
 

+ 2 - 0
drivers/iio/potentiostat/lmp91000.c

@@ -411,12 +411,14 @@ static int lmp91000_remove(struct i2c_client *client)
 
 static const struct of_device_id lmp91000_of_match[] = {
 	{ .compatible = "ti,lmp91000", },
+	{ .compatible = "ti,lmp91002", },
 	{ },
 };
 MODULE_DEVICE_TABLE(of, lmp91000_of_match);
 
 static const struct i2c_device_id lmp91000_id[] = {
 	{ "lmp91000", 0 },
+	{ "lmp91002", 0 },
 	{}
 };
 MODULE_DEVICE_TABLE(i2c, lmp91000_id);

+ 17 - 0
drivers/iio/resolver/Kconfig

@@ -0,0 +1,17 @@
+#
+# Resolver/Synchro drivers
+#
+menu "Resolver to digital converters"
+
+config AD2S1200
+	tristate "Analog Devices ad2s1200/ad2s1205 driver"
+	depends on SPI
+	depends on GPIOLIB || COMPILE_TEST
+	help
+	  Say yes here to build support for Analog Devices spi resolver
+	  to digital converters, ad2s1200 and ad2s1205, provides direct access
+	  via sysfs.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ad2s1200.
+endmenu

+ 5 - 0
drivers/iio/resolver/Makefile

@@ -0,0 +1,5 @@
+#
+# Makefile for Resolver/Synchro drivers
+#
+
+obj-$(CONFIG_AD2S1200) += ad2s1200.o

+ 94 - 52
drivers/staging/iio/resolver/ad2s1200.c → drivers/iio/resolver/ad2s1200.c

@@ -2,18 +2,19 @@
  * ad2s1200.c simple support for the ADI Resolver to Digital Converters:
  * AD2S1200/1205
  *
+ * Copyright (c) 2018-2018 David Veenstra <davidjulianveenstra@gmail.com>
  * Copyright (c) 2010-2010 Analog Devices Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
- *
  */
 
 #include <linux/bitops.h>
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/spi/spi.h>
@@ -25,19 +26,24 @@
 
 #define DRV_NAME "ad2s1200"
 
-/* input pin sample and rdvel is controlled by driver */
-#define AD2S1200_PN	2
-
 /* input clock on serial interface */
 #define AD2S1200_HZ	8192000
 /* clock period in nano second */
 #define AD2S1200_TSCLK	(1000000000 / AD2S1200_HZ)
 
+/**
+ * struct ad2s1200_state - driver instance specific data.
+ * @lock:	protects both the GPIO pins and the rx buffer.
+ * @sdev:	spi device.
+ * @sample:	GPIO pin SAMPLE.
+ * @rdvel:	GPIO pin RDVEL.
+ * @rx:		buffer for spi transfers.
+ */
 struct ad2s1200_state {
 	struct mutex lock;
 	struct spi_device *sdev;
-	int sample;
-	int rdvel;
+	struct gpio_desc *sample;
+	struct gpio_desc *rdvel;
 	__be16 rx ____cacheline_aligned;
 };
 
@@ -48,39 +54,62 @@ static int ad2s1200_read_raw(struct iio_dev *indio_dev,
 			     long m)
 {
 	struct ad2s1200_state *st = iio_priv(indio_dev);
-	int ret = 0;
-
-	mutex_lock(&st->lock);
-	gpio_set_value(st->sample, 0);
+	int ret;
+
+	switch (m) {
+	case IIO_CHAN_INFO_SCALE:
+		switch (chan->type) {
+		case IIO_ANGL:
+			/* 2 * Pi / (2^12 - 1) ~= 0.001534355 */
+			*val = 0;
+			*val2 = 1534355;
+			return IIO_VAL_INT_PLUS_NANO;
+		case IIO_ANGL_VEL:
+			/* 2 * Pi ~= 6.283185 */
+			*val = 6;
+			*val2 = 283185;
+			return IIO_VAL_INT_PLUS_MICRO;
+		default:
+			return -EINVAL;
+		}
+		break;
+	case IIO_CHAN_INFO_RAW:
+		mutex_lock(&st->lock);
+		gpiod_set_value(st->sample, 0);
+
+		/* delay (6 * AD2S1200_TSCLK + 20) nano seconds */
+		udelay(1);
+		gpiod_set_value(st->sample, 1);
+		gpiod_set_value(st->rdvel, !!(chan->type == IIO_ANGL));
+
+		ret = spi_read(st->sdev, &st->rx, 2);
+		if (ret < 0) {
+			mutex_unlock(&st->lock);
+			return ret;
+		}
 
-	/* delay (6 * AD2S1200_TSCLK + 20) nano seconds */
-	udelay(1);
-	gpio_set_value(st->sample, 1);
-	gpio_set_value(st->rdvel, !!(chan->type == IIO_ANGL));
+		switch (chan->type) {
+		case IIO_ANGL:
+			*val = be16_to_cpup(&st->rx) >> 4;
+			break;
+		case IIO_ANGL_VEL:
+			*val = sign_extend32(be16_to_cpup(&st->rx) >> 4, 11);
+			break;
+		default:
+			mutex_unlock(&st->lock);
+			return -EINVAL;
+		}
 
-	ret = spi_read(st->sdev, &st->rx, 2);
-	if (ret < 0) {
+		/* delay (2 * AD2S1200_TSCLK + 20) ns for sample pulse */
+		udelay(1);
 		mutex_unlock(&st->lock);
-		return ret;
-	}
 
-	switch (chan->type) {
-	case IIO_ANGL:
-		*val = be16_to_cpup(&st->rx) >> 4;
-		break;
-	case IIO_ANGL_VEL:
-		*val = sign_extend32(be16_to_cpup(&st->rx) >> 4, 11);
-		break;
+		return IIO_VAL_INT;
 	default:
-		mutex_unlock(&st->lock);
-		return -EINVAL;
+		break;
 	}
 
-	/* delay (2 * AD2S1200_TSCLK + 20) ns for sample pulse */
-	udelay(1);
-	mutex_unlock(&st->lock);
-
-	return IIO_VAL_INT;
+	return -EINVAL;
 }
 
 static const struct iio_chan_spec ad2s1200_channels[] = {
@@ -89,11 +118,13 @@ static const struct iio_chan_spec ad2s1200_channels[] = {
 		.indexed = 1,
 		.channel = 0,
 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
 	}, {
 		.type = IIO_ANGL_VEL,
 		.indexed = 1,
 		.channel = 0,
 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
 	}
 };
 
@@ -103,20 +134,9 @@ static const struct iio_info ad2s1200_info = {
 
 static int ad2s1200_probe(struct spi_device *spi)
 {
-	unsigned short *pins = spi->dev.platform_data;
 	struct ad2s1200_state *st;
 	struct iio_dev *indio_dev;
-	int pn, ret = 0;
-
-	for (pn = 0; pn < AD2S1200_PN; pn++) {
-		ret = devm_gpio_request_one(&spi->dev, pins[pn], GPIOF_DIR_OUT,
-					    DRV_NAME);
-		if (ret) {
-			dev_err(&spi->dev, "request gpio pin %d failed\n",
-				pins[pn]);
-			return ret;
-		}
-	}
+	int ret;
 
 	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 	if (!indio_dev)
@@ -126,8 +146,20 @@ static int ad2s1200_probe(struct spi_device *spi)
 	st = iio_priv(indio_dev);
 	mutex_init(&st->lock);
 	st->sdev = spi;
-	st->sample = pins[0];
-	st->rdvel = pins[1];
+
+	st->sample = devm_gpiod_get(&spi->dev, "adi,sample", GPIOD_OUT_LOW);
+	if (IS_ERR(st->sample)) {
+		dev_err(&spi->dev, "Failed to claim SAMPLE gpio: err=%ld\n",
+			PTR_ERR(st->sample));
+		return PTR_ERR(st->sample);
+	}
+
+	st->rdvel = devm_gpiod_get(&spi->dev, "adi,rdvel", GPIOD_OUT_LOW);
+	if (IS_ERR(st->rdvel)) {
+		dev_err(&spi->dev, "Failed to claim RDVEL gpio: err=%ld\n",
+			PTR_ERR(st->rdvel));
+		return PTR_ERR(st->rdvel);
+	}
 
 	indio_dev->dev.parent = &spi->dev;
 	indio_dev->info = &ad2s1200_info;
@@ -136,17 +168,25 @@ static int ad2s1200_probe(struct spi_device *spi)
 	indio_dev->num_channels = ARRAY_SIZE(ad2s1200_channels);
 	indio_dev->name = spi_get_device_id(spi)->name;
 
-	ret = devm_iio_device_register(&spi->dev, indio_dev);
-	if (ret)
-		return ret;
-
 	spi->max_speed_hz = AD2S1200_HZ;
 	spi->mode = SPI_MODE_3;
-	spi_setup(spi);
+	ret = spi_setup(spi);
+
+	if (ret < 0) {
+		dev_err(&spi->dev, "spi_setup failed!\n");
+		return ret;
+	}
 
-	return 0;
+	return devm_iio_device_register(&spi->dev, indio_dev);
 }
 
+static const struct of_device_id ad2s1200_of_match[] = {
+	{ .compatible = "adi,ad2s1200", },
+	{ .compatible = "adi,ad2s1205", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, ad2s1200_of_match);
+
 static const struct spi_device_id ad2s1200_id[] = {
 	{ "ad2s1200" },
 	{ "ad2s1205" },
@@ -157,12 +197,14 @@ MODULE_DEVICE_TABLE(spi, ad2s1200_id);
 static struct spi_driver ad2s1200_driver = {
 	.driver = {
 		.name = DRV_NAME,
+		.of_match_table = of_match_ptr(ad2s1200_of_match),
 	},
 	.probe = ad2s1200_probe,
 	.id_table = ad2s1200_id,
 };
 module_spi_driver(ad2s1200_driver);
 
+MODULE_AUTHOR("David Veenstra <davidjulianveenstra@gmail.com>");
 MODULE_AUTHOR("Graff Yang <graff.yang@gmail.com>");
 MODULE_DESCRIPTION("Analog Devices AD2S1200/1205 Resolver to Digital SPI driver");
 MODULE_LICENSE("GPL v2");

+ 0 - 1
drivers/staging/iio/Kconfig

@@ -11,7 +11,6 @@ source "drivers/staging/iio/cdc/Kconfig"
 source "drivers/staging/iio/frequency/Kconfig"
 source "drivers/staging/iio/gyro/Kconfig"
 source "drivers/staging/iio/impedance-analyzer/Kconfig"
-source "drivers/staging/iio/light/Kconfig"
 source "drivers/staging/iio/meter/Kconfig"
 source "drivers/staging/iio/resolver/Kconfig"
 

+ 0 - 1
drivers/staging/iio/Makefile

@@ -10,6 +10,5 @@ obj-y += cdc/
 obj-y += frequency/
 obj-y += gyro/
 obj-y += impedance-analyzer/
-obj-y += light/
 obj-y += meter/
 obj-y += resolver/

+ 0 - 14
drivers/staging/iio/light/Kconfig

@@ -1,14 +0,0 @@
-#
-# Light sensors
-#
-menu "Light sensors"
-
-config TSL2x7x
-	tristate "TAOS TSL/TMD2x71 and TSL/TMD2x72 Family of light and proximity sensors"
-	depends on I2C
-	help
-	 Support for: tsl2571, tsl2671, tmd2671, tsl2771, tmd2771, tsl2572, tsl2672,
-	 tmd2672, tsl2772, tmd2772 devices.
-	 Provides iio_events and direct access via sysfs.
-
-endmenu

+ 0 - 5
drivers/staging/iio/light/Makefile

@@ -1,5 +0,0 @@
-#
-# Makefile for industrial I/O Light sensors
-#
-
-obj-$(CONFIG_TSL2x7x)	+= tsl2x7x.o

+ 0 - 42
drivers/staging/iio/meter/Kconfig

@@ -3,48 +3,6 @@
 #
 menu "Active energy metering IC"
 
-config ADE7753
-	tristate "Analog Devices ADE7753/6 Single-Phase Multifunction Metering IC Driver"
-	depends on SPI
-	help
-	  Say yes here to build support for Analog Devices ADE7753 Single-Phase Multifunction
-	  Metering IC with di/dt Sensor Interface.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called ade7753.
-
-config ADE7754
-	tristate "Analog Devices ADE7754 Polyphase Multifunction Energy Metering IC Driver"
-	depends on SPI
-	help
-	  Say yes here to build support for Analog Devices ADE7754 Polyphase
-	  Multifunction Energy Metering IC Driver.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called ade7754.
-
-config ADE7758
-	tristate "Analog Devices ADE7758 Poly Phase Multifunction Energy Metering IC Driver"
-	depends on SPI
-	select IIO_TRIGGER if IIO_BUFFER
-	select IIO_KFIFO_BUF if IIO_BUFFER
-	help
-	  Say yes here to build support for Analog Devices ADE7758 Polyphase
-	  Multifunction Energy Metering IC with Per Phase Information Driver.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called ade7758.
-
-config ADE7759
-	tristate "Analog Devices ADE7759 Active Energy Metering IC Driver"
-	depends on SPI
-	help
-	  Say yes here to build support for Analog Devices ADE7758 Active Energy
-	  Metering IC with di/dt Sensor Interface.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called ade7759.
-
 config ADE7854
 	tristate "Analog Devices ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC Driver"
 	depends on SPI || I2C

+ 0 - 8
drivers/staging/iio/meter/Makefile

@@ -3,14 +3,6 @@
 # Makefile for metering ic drivers
 #
 
-obj-$(CONFIG_ADE7753) += ade7753.o
-obj-$(CONFIG_ADE7754) += ade7754.o
-
-ade7758-y             := ade7758_core.o
-ade7758-$(CONFIG_IIO_BUFFER) += ade7758_ring.o ade7758_trigger.o
-obj-$(CONFIG_ADE7758) += ade7758.o
-
-obj-$(CONFIG_ADE7759) += ade7759.o
 obj-$(CONFIG_ADE7854) += ade7854.o
 obj-$(CONFIG_ADE7854_I2C) += ade7854-i2c.o
 obj-$(CONFIG_ADE7854_SPI) += ade7854-spi.o

+ 0 - 630
drivers/staging/iio/meter/ade7753.c

@@ -1,630 +0,0 @@
-/*
- * ADE7753 Single-Phase Multifunction Metering IC with di/dt Sensor Interface
- *
- * Copyright 2010 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-#include <linux/spi/spi.h>
-#include "meter.h"
-
-#define ADE7753_WAVEFORM   0x01
-#define ADE7753_AENERGY    0x02
-#define ADE7753_RAENERGY   0x03
-#define ADE7753_LAENERGY   0x04
-#define ADE7753_VAENERGY   0x05
-#define ADE7753_RVAENERGY  0x06
-#define ADE7753_LVAENERGY  0x07
-#define ADE7753_LVARENERGY 0x08
-#define ADE7753_MODE       0x09
-#define ADE7753_IRQEN      0x0A
-#define ADE7753_STATUS     0x0B
-#define ADE7753_RSTSTATUS  0x0C
-#define ADE7753_CH1OS      0x0D
-#define ADE7753_CH2OS      0x0E
-#define ADE7753_GAIN       0x0F
-#define ADE7753_PHCAL      0x10
-#define ADE7753_APOS       0x11
-#define ADE7753_WGAIN      0x12
-#define ADE7753_WDIV       0x13
-#define ADE7753_CFNUM      0x14
-#define ADE7753_CFDEN      0x15
-#define ADE7753_IRMS       0x16
-#define ADE7753_VRMS       0x17
-#define ADE7753_IRMSOS     0x18
-#define ADE7753_VRMSOS     0x19
-#define ADE7753_VAGAIN     0x1A
-#define ADE7753_VADIV      0x1B
-#define ADE7753_LINECYC    0x1C
-#define ADE7753_ZXTOUT     0x1D
-#define ADE7753_SAGCYC     0x1E
-#define ADE7753_SAGLVL     0x1F
-#define ADE7753_IPKLVL     0x20
-#define ADE7753_VPKLVL     0x21
-#define ADE7753_IPEAK      0x22
-#define ADE7753_RSTIPEAK   0x23
-#define ADE7753_VPEAK      0x24
-#define ADE7753_RSTVPEAK   0x25
-#define ADE7753_TEMP       0x26
-#define ADE7753_PERIOD     0x27
-#define ADE7753_TMODE      0x3D
-#define ADE7753_CHKSUM     0x3E
-#define ADE7753_DIEREV     0x3F
-
-#define ADE7753_READ_REG(a)    a
-#define ADE7753_WRITE_REG(a) ((a) | 0x80)
-
-#define ADE7753_MAX_TX    4
-#define ADE7753_MAX_RX    4
-#define ADE7753_STARTUP_DELAY 1000
-
-#define ADE7753_SPI_SLOW    (u32)(300 * 1000)
-#define ADE7753_SPI_BURST   (u32)(1000 * 1000)
-#define ADE7753_SPI_FAST    (u32)(2000 * 1000)
-
-/**
- * struct ade7753_state - device instance specific data
- * @us:         actual spi_device
- * @tx:         transmit buffer
- * @rx:         receive buffer
- * @buf_lock:       mutex to protect tx, rx and write frequency
- **/
-struct ade7753_state {
-	struct spi_device   *us;
-	struct mutex        buf_lock;
-	u8          tx[ADE7753_MAX_TX] ____cacheline_aligned;
-	u8          rx[ADE7753_MAX_RX];
-};
-
-static int ade7753_spi_write_reg_8(struct device *dev,
-				   u8 reg_address,
-				   u8 val)
-{
-	int ret;
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ade7753_state *st = iio_priv(indio_dev);
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADE7753_WRITE_REG(reg_address);
-	st->tx[1] = val;
-
-	ret = spi_write(st->us, st->tx, 2);
-	mutex_unlock(&st->buf_lock);
-
-	return ret;
-}
-
-static int __ade7753_spi_write_reg_16(struct device *dev, u8 reg_address,
-				      u16 value)
-{
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ade7753_state *st = iio_priv(indio_dev);
-
-	st->tx[0] = ADE7753_WRITE_REG(reg_address);
-	st->tx[1] = (value >> 8) & 0xFF;
-	st->tx[2] = value & 0xFF;
-
-	return spi_write(st->us, st->tx, 3);
-}
-
-static int ade7753_spi_write_reg_16(struct device *dev, u8 reg_address,
-				    u16 value)
-{
-	int ret;
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ade7753_state *st = iio_priv(indio_dev);
-
-	mutex_lock(&st->buf_lock);
-	ret = __ade7753_spi_write_reg_16(dev, reg_address, value);
-	mutex_unlock(&st->buf_lock);
-
-	return ret;
-}
-
-static int ade7753_spi_read_reg_8(struct device *dev,
-				  u8 reg_address,
-				  u8 *val)
-{
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ade7753_state *st = iio_priv(indio_dev);
-	ssize_t ret;
-
-	ret = spi_w8r8(st->us, ADE7753_READ_REG(reg_address));
-	if (ret < 0) {
-		dev_err(&st->us->dev, "problem when reading 8 bit register 0x%02X",
-			reg_address);
-		return ret;
-	}
-	*val = ret;
-
-	return 0;
-}
-
-static int ade7753_spi_read_reg_16(struct device *dev,
-				   u8 reg_address,
-				   u16 *val)
-{
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ade7753_state *st = iio_priv(indio_dev);
-	ssize_t ret;
-
-	ret = spi_w8r16be(st->us, ADE7753_READ_REG(reg_address));
-	if (ret < 0) {
-		dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
-			reg_address);
-		return ret;
-	}
-
-	*val = ret;
-
-	return 0;
-}
-
-static int ade7753_spi_read_reg_24(struct device *dev,
-				   u8 reg_address,
-				   u32 *val)
-{
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ade7753_state *st = iio_priv(indio_dev);
-	int ret;
-	struct spi_transfer xfers[] = {
-		{
-			.tx_buf = st->tx,
-			.bits_per_word = 8,
-			.len = 1,
-		}, {
-			.rx_buf = st->tx,
-			.bits_per_word = 8,
-			.len = 3,
-		}
-	};
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADE7753_READ_REG(reg_address);
-
-	ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
-	if (ret) {
-		dev_err(&st->us->dev, "problem when reading 24 bit register 0x%02X",
-			reg_address);
-		goto error_ret;
-	}
-	*val = (st->rx[0] << 16) | (st->rx[1] << 8) | st->rx[2];
-
-error_ret:
-	mutex_unlock(&st->buf_lock);
-	return ret;
-}
-
-static ssize_t ade7753_read_8bit(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	int ret;
-	u8 val;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = ade7753_spi_read_reg_8(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	return sprintf(buf, "%u\n", val);
-}
-
-static ssize_t ade7753_read_16bit(struct device *dev,
-				  struct device_attribute *attr,
-				  char *buf)
-{
-	int ret;
-	u16 val;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = ade7753_spi_read_reg_16(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	return sprintf(buf, "%u\n", val);
-}
-
-static ssize_t ade7753_read_24bit(struct device *dev,
-				  struct device_attribute *attr,
-				  char *buf)
-{
-	int ret;
-	u32 val;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = ade7753_spi_read_reg_24(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	return sprintf(buf, "%u\n", val);
-}
-
-static ssize_t ade7753_write_8bit(struct device *dev,
-				  struct device_attribute *attr,
-				  const char *buf,
-				  size_t len)
-{
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-	u8 val;
-
-	ret = kstrtou8(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = ade7753_spi_write_reg_8(dev, this_attr->address, val);
-
-error_ret:
-	return ret ? ret : len;
-}
-
-static ssize_t ade7753_write_16bit(struct device *dev,
-				   struct device_attribute *attr,
-				   const char *buf,
-				   size_t len)
-{
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-	u16 val;
-
-	ret = kstrtou16(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = ade7753_spi_write_reg_16(dev, this_attr->address, val);
-
-error_ret:
-	return ret ? ret : len;
-}
-
-static int ade7753_reset(struct device *dev)
-{
-	u16 val;
-	int ret;
-
-	ret = ade7753_spi_read_reg_16(dev, ADE7753_MODE, &val);
-	if (ret)
-		return ret;
-
-	val |= BIT(6); /* Software Chip Reset */
-
-	return ade7753_spi_write_reg_16(dev, ADE7753_MODE, val);
-}
-
-static IIO_DEV_ATTR_AENERGY(ade7753_read_24bit, ADE7753_AENERGY);
-static IIO_DEV_ATTR_LAENERGY(ade7753_read_24bit, ADE7753_LAENERGY);
-static IIO_DEV_ATTR_VAENERGY(ade7753_read_24bit, ADE7753_VAENERGY);
-static IIO_DEV_ATTR_LVAENERGY(ade7753_read_24bit, ADE7753_LVAENERGY);
-static IIO_DEV_ATTR_CFDEN(0644,
-		ade7753_read_16bit,
-		ade7753_write_16bit,
-		ADE7753_CFDEN);
-static IIO_DEV_ATTR_CFNUM(0644,
-		ade7753_read_8bit,
-		ade7753_write_8bit,
-		ADE7753_CFNUM);
-static IIO_DEV_ATTR_CHKSUM(ade7753_read_8bit, ADE7753_CHKSUM);
-static IIO_DEV_ATTR_PHCAL(0644,
-		ade7753_read_16bit,
-		ade7753_write_16bit,
-		ADE7753_PHCAL);
-static IIO_DEV_ATTR_APOS(0644,
-		ade7753_read_16bit,
-		ade7753_write_16bit,
-		ADE7753_APOS);
-static IIO_DEV_ATTR_SAGCYC(0644,
-		ade7753_read_8bit,
-		ade7753_write_8bit,
-		ADE7753_SAGCYC);
-static IIO_DEV_ATTR_SAGLVL(0644,
-		ade7753_read_8bit,
-		ade7753_write_8bit,
-		ADE7753_SAGLVL);
-static IIO_DEV_ATTR_LINECYC(0644,
-		ade7753_read_8bit,
-		ade7753_write_8bit,
-		ADE7753_LINECYC);
-static IIO_DEV_ATTR_WDIV(0644,
-		ade7753_read_8bit,
-		ade7753_write_8bit,
-		ADE7753_WDIV);
-static IIO_DEV_ATTR_IRMS(0644,
-		ade7753_read_24bit,
-		NULL,
-		ADE7753_IRMS);
-static IIO_DEV_ATTR_VRMS(0444,
-		ade7753_read_24bit,
-		NULL,
-		ADE7753_VRMS);
-static IIO_DEV_ATTR_IRMSOS(0644,
-		ade7753_read_16bit,
-		ade7753_write_16bit,
-		ADE7753_IRMSOS);
-static IIO_DEV_ATTR_VRMSOS(0644,
-		ade7753_read_16bit,
-		ade7753_write_16bit,
-		ADE7753_VRMSOS);
-static IIO_DEV_ATTR_WGAIN(0644,
-		ade7753_read_16bit,
-		ade7753_write_16bit,
-		ADE7753_WGAIN);
-static IIO_DEV_ATTR_VAGAIN(0644,
-		ade7753_read_16bit,
-		ade7753_write_16bit,
-		ADE7753_VAGAIN);
-static IIO_DEV_ATTR_PGA_GAIN(0644,
-		ade7753_read_16bit,
-		ade7753_write_16bit,
-		ADE7753_GAIN);
-static IIO_DEV_ATTR_IPKLVL(0644,
-		ade7753_read_8bit,
-		ade7753_write_8bit,
-		ADE7753_IPKLVL);
-static IIO_DEV_ATTR_VPKLVL(0644,
-		ade7753_read_8bit,
-		ade7753_write_8bit,
-		ADE7753_VPKLVL);
-static IIO_DEV_ATTR_IPEAK(0444,
-		ade7753_read_24bit,
-		NULL,
-		ADE7753_IPEAK);
-static IIO_DEV_ATTR_VPEAK(0444,
-		ade7753_read_24bit,
-		NULL,
-		ADE7753_VPEAK);
-static IIO_DEV_ATTR_VPERIOD(0444,
-		ade7753_read_16bit,
-		NULL,
-		ADE7753_PERIOD);
-
-static IIO_DEVICE_ATTR(choff_1, 0644,
-			ade7753_read_8bit,
-			ade7753_write_8bit,
-			ADE7753_CH1OS);
-
-static IIO_DEVICE_ATTR(choff_2, 0644,
-			ade7753_read_8bit,
-			ade7753_write_8bit,
-			ADE7753_CH2OS);
-
-static int ade7753_set_irq(struct device *dev, bool enable)
-{
-	int ret;
-	u8 irqen;
-
-	ret = ade7753_spi_read_reg_8(dev, ADE7753_IRQEN, &irqen);
-	if (ret)
-		goto error_ret;
-
-	if (enable)
-		irqen |= BIT(3); /* Enables an interrupt when a data is
-				  * present in the waveform register
-				  */
-	else
-		irqen &= ~BIT(3);
-
-	ret = ade7753_spi_write_reg_8(dev, ADE7753_IRQEN, irqen);
-
-error_ret:
-	return ret;
-}
-
-/* Power down the device */
-static int ade7753_stop_device(struct device *dev)
-{
-	u16 val;
-	int ret;
-
-	ret = ade7753_spi_read_reg_16(dev, ADE7753_MODE, &val);
-	if (ret)
-		return ret;
-
-	val |= BIT(4);  /* AD converters can be turned off */
-
-	return ade7753_spi_write_reg_16(dev, ADE7753_MODE, val);
-}
-
-static int ade7753_initial_setup(struct iio_dev *indio_dev)
-{
-	int ret;
-	struct device *dev = &indio_dev->dev;
-	struct ade7753_state *st = iio_priv(indio_dev);
-
-	/* use low spi speed for init */
-	st->us->mode = SPI_MODE_3;
-	spi_setup(st->us);
-
-	/* Disable IRQ */
-	ret = ade7753_set_irq(dev, false);
-	if (ret) {
-		dev_err(dev, "disable irq failed");
-		goto err_ret;
-	}
-
-	ade7753_reset(dev);
-	usleep_range(ADE7753_STARTUP_DELAY, ADE7753_STARTUP_DELAY + 100);
-
-err_ret:
-	return ret;
-}
-
-static ssize_t ade7753_read_frequency(struct device *dev,
-				      struct device_attribute *attr,
-				      char *buf)
-{
-	int ret;
-	u16 t;
-	int sps;
-
-	ret = ade7753_spi_read_reg_16(dev, ADE7753_MODE, &t);
-	if (ret)
-		return ret;
-
-	t = (t >> 11) & 0x3;
-	sps = 27900 / (1 + t);
-
-	return sprintf(buf, "%d\n", sps);
-}
-
-static ssize_t ade7753_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 ade7753_state *st = iio_priv(indio_dev);
-	u16 val;
-	int ret;
-	u16 reg, t;
-
-	ret = kstrtou16(buf, 10, &val);
-	if (ret)
-		return ret;
-	if (!val)
-		return -EINVAL;
-
-	mutex_lock(&st->buf_lock);
-
-	t = 27900 / val;
-	if (t > 0)
-		t--;
-
-	if (t > 1)
-		st->us->max_speed_hz = ADE7753_SPI_SLOW;
-	else
-		st->us->max_speed_hz = ADE7753_SPI_FAST;
-
-	ret = ade7753_spi_read_reg_16(dev, ADE7753_MODE, &reg);
-	if (ret)
-		goto out;
-
-	reg &= ~(3 << 11);
-	reg |= t << 11;
-
-	ret = __ade7753_spi_write_reg_16(dev, ADE7753_MODE, reg);
-
-out:
-	mutex_unlock(&st->buf_lock);
-
-	return ret ? ret : len;
-}
-
-static IIO_DEV_ATTR_TEMP_RAW(ade7753_read_8bit);
-static IIO_CONST_ATTR(in_temp_offset, "-25 C");
-static IIO_CONST_ATTR(in_temp_scale, "0.67 C");
-
-static IIO_DEV_ATTR_SAMP_FREQ(0644,
-		ade7753_read_frequency,
-		ade7753_write_frequency);
-
-static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("27900 14000 7000 3500");
-
-static struct attribute *ade7753_attributes[] = {
-	&iio_dev_attr_in_temp_raw.dev_attr.attr,
-	&iio_const_attr_in_temp_offset.dev_attr.attr,
-	&iio_const_attr_in_temp_scale.dev_attr.attr,
-	&iio_dev_attr_sampling_frequency.dev_attr.attr,
-	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
-	&iio_dev_attr_phcal.dev_attr.attr,
-	&iio_dev_attr_cfden.dev_attr.attr,
-	&iio_dev_attr_aenergy.dev_attr.attr,
-	&iio_dev_attr_laenergy.dev_attr.attr,
-	&iio_dev_attr_vaenergy.dev_attr.attr,
-	&iio_dev_attr_lvaenergy.dev_attr.attr,
-	&iio_dev_attr_cfnum.dev_attr.attr,
-	&iio_dev_attr_apos.dev_attr.attr,
-	&iio_dev_attr_sagcyc.dev_attr.attr,
-	&iio_dev_attr_saglvl.dev_attr.attr,
-	&iio_dev_attr_linecyc.dev_attr.attr,
-	&iio_dev_attr_chksum.dev_attr.attr,
-	&iio_dev_attr_pga_gain.dev_attr.attr,
-	&iio_dev_attr_wgain.dev_attr.attr,
-	&iio_dev_attr_choff_1.dev_attr.attr,
-	&iio_dev_attr_choff_2.dev_attr.attr,
-	&iio_dev_attr_wdiv.dev_attr.attr,
-	&iio_dev_attr_irms.dev_attr.attr,
-	&iio_dev_attr_vrms.dev_attr.attr,
-	&iio_dev_attr_irmsos.dev_attr.attr,
-	&iio_dev_attr_vrmsos.dev_attr.attr,
-	&iio_dev_attr_vagain.dev_attr.attr,
-	&iio_dev_attr_ipklvl.dev_attr.attr,
-	&iio_dev_attr_vpklvl.dev_attr.attr,
-	&iio_dev_attr_ipeak.dev_attr.attr,
-	&iio_dev_attr_vpeak.dev_attr.attr,
-	&iio_dev_attr_vperiod.dev_attr.attr,
-	NULL,
-};
-
-static const struct attribute_group ade7753_attribute_group = {
-	.attrs = ade7753_attributes,
-};
-
-static const struct iio_info ade7753_info = {
-	.attrs = &ade7753_attribute_group,
-};
-
-static int ade7753_probe(struct spi_device *spi)
-{
-	int ret;
-	struct ade7753_state *st;
-	struct iio_dev *indio_dev;
-
-	/* setup the industrialio driver allocated elements */
-	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
-	if (!indio_dev)
-		return -ENOMEM;
-	/* this is only used for removal purposes */
-	spi_set_drvdata(spi, indio_dev);
-
-	st = iio_priv(indio_dev);
-	st->us = spi;
-	mutex_init(&st->buf_lock);
-
-	indio_dev->name = spi->dev.driver->name;
-	indio_dev->dev.parent = &spi->dev;
-	indio_dev->info = &ade7753_info;
-	indio_dev->modes = INDIO_DIRECT_MODE;
-
-	/* Get the device into a sane initial state */
-	ret = ade7753_initial_setup(indio_dev);
-	if (ret)
-		return ret;
-
-	return iio_device_register(indio_dev);
-}
-
-static int ade7753_remove(struct spi_device *spi)
-{
-	struct iio_dev *indio_dev = spi_get_drvdata(spi);
-
-	iio_device_unregister(indio_dev);
-	ade7753_stop_device(&indio_dev->dev);
-
-	return 0;
-}
-
-static struct spi_driver ade7753_driver = {
-	.driver = {
-		.name = "ade7753",
-	},
-	.probe = ade7753_probe,
-	.remove = ade7753_remove,
-};
-module_spi_driver(ade7753_driver);
-
-MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
-MODULE_DESCRIPTION("Analog Devices ADE7753/6 Single-Phase Multifunction Meter");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("spi:ade7753");

+ 0 - 664
drivers/staging/iio/meter/ade7754.c

@@ -1,664 +0,0 @@
-/*
- * ADE7754 Polyphase Multifunction Energy Metering IC Driver
- *
- * Copyright 2010 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-#include "meter.h"
-
-#define ADE7754_AENERGY   0x01
-#define ADE7754_RAENERGY  0x02
-#define ADE7754_LAENERGY  0x03
-#define ADE7754_VAENERGY  0x04
-#define ADE7754_RVAENERGY 0x05
-#define ADE7754_LVAENERGY 0x06
-#define ADE7754_PERIOD    0x07
-#define ADE7754_TEMP      0x08
-#define ADE7754_WFORM     0x09
-#define ADE7754_OPMODE    0x0A
-#define ADE7754_MMODE     0x0B
-#define ADE7754_WAVMODE   0x0C
-#define ADE7754_WATMODE   0x0D
-#define ADE7754_VAMODE    0x0E
-#define ADE7754_IRQEN     0x0F
-#define ADE7754_STATUS    0x10
-#define ADE7754_RSTATUS   0x11
-#define ADE7754_ZXTOUT    0x12
-#define ADE7754_LINCYC    0x13
-#define ADE7754_SAGCYC    0x14
-#define ADE7754_SAGLVL    0x15
-#define ADE7754_VPEAK     0x16
-#define ADE7754_IPEAK     0x17
-#define ADE7754_GAIN      0x18
-#define ADE7754_AWG       0x19
-#define ADE7754_BWG       0x1A
-#define ADE7754_CWG       0x1B
-#define ADE7754_AVAG      0x1C
-#define ADE7754_BVAG      0x1D
-#define ADE7754_CVAG      0x1E
-#define ADE7754_APHCAL    0x1F
-#define ADE7754_BPHCAL    0x20
-#define ADE7754_CPHCAL    0x21
-#define ADE7754_AAPOS     0x22
-#define ADE7754_BAPOS     0x23
-#define ADE7754_CAPOS     0x24
-#define ADE7754_CFNUM     0x25
-#define ADE7754_CFDEN     0x26
-#define ADE7754_WDIV      0x27
-#define ADE7754_VADIV     0x28
-#define ADE7754_AIRMS     0x29
-#define ADE7754_BIRMS     0x2A
-#define ADE7754_CIRMS     0x2B
-#define ADE7754_AVRMS     0x2C
-#define ADE7754_BVRMS     0x2D
-#define ADE7754_CVRMS     0x2E
-#define ADE7754_AIRMSOS   0x2F
-#define ADE7754_BIRMSOS   0x30
-#define ADE7754_CIRMSOS   0x31
-#define ADE7754_AVRMSOS   0x32
-#define ADE7754_BVRMSOS   0x33
-#define ADE7754_CVRMSOS   0x34
-#define ADE7754_AAPGAIN   0x35
-#define ADE7754_BAPGAIN   0x36
-#define ADE7754_CAPGAIN   0x37
-#define ADE7754_AVGAIN    0x38
-#define ADE7754_BVGAIN    0x39
-#define ADE7754_CVGAIN    0x3A
-#define ADE7754_CHKSUM    0x3E
-#define ADE7754_VERSION   0x3F
-
-#define ADE7754_READ_REG(a)    a
-#define ADE7754_WRITE_REG(a) ((a) | 0x80)
-
-#define ADE7754_MAX_TX    4
-#define ADE7754_MAX_RX    4
-#define ADE7754_STARTUP_DELAY 1000
-
-#define ADE7754_SPI_SLOW	(u32)(300 * 1000)
-#define ADE7754_SPI_BURST	(u32)(1000 * 1000)
-#define ADE7754_SPI_FAST	(u32)(2000 * 1000)
-
-/**
- * struct ade7754_state - device instance specific data
- * @us:			actual spi_device
- * @buf_lock:		mutex to protect tx, rx and write frequency
- * @tx:			transmit buffer
- * @rx:			receive buffer
- **/
-struct ade7754_state {
-	struct spi_device	*us;
-	struct mutex		buf_lock;
-	u8			tx[ADE7754_MAX_TX] ____cacheline_aligned;
-	u8			rx[ADE7754_MAX_RX];
-};
-
-/* Unlocked version of ade7754_spi_write_reg_8 function */
-static int __ade7754_spi_write_reg_8(struct device *dev, u8 reg_address, u8 val)
-{
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ade7754_state *st = iio_priv(indio_dev);
-
-	st->tx[0] = ADE7754_WRITE_REG(reg_address);
-	st->tx[1] = val;
-	return spi_write(st->us, st->tx, 2);
-}
-
-static int ade7754_spi_write_reg_8(struct device *dev, u8 reg_address, u8 val)
-{
-	int ret;
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ade7754_state *st = iio_priv(indio_dev);
-
-	mutex_lock(&st->buf_lock);
-	ret = __ade7754_spi_write_reg_8(dev, reg_address, val);
-	mutex_unlock(&st->buf_lock);
-
-	return ret;
-}
-
-static int ade7754_spi_write_reg_16(struct device *dev,
-				    u8 reg_address, u16 val)
-{
-	int ret;
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ade7754_state *st = iio_priv(indio_dev);
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADE7754_WRITE_REG(reg_address);
-	st->tx[1] = (val >> 8) & 0xFF;
-	st->tx[2] = val & 0xFF;
-	ret = spi_write(st->us, st->tx, 3);
-	mutex_unlock(&st->buf_lock);
-
-	return ret;
-}
-
-static int ade7754_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val)
-{
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ade7754_state *st = iio_priv(indio_dev);
-	int ret;
-
-	ret = spi_w8r8(st->us, ADE7754_READ_REG(reg_address));
-	if (ret < 0) {
-		dev_err(&st->us->dev, "problem when reading 8 bit register 0x%02X",
-			reg_address);
-		return ret;
-	}
-	*val = ret;
-
-	return 0;
-}
-
-static int ade7754_spi_read_reg_16(struct device *dev,
-				   u8 reg_address, u16 *val)
-{
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ade7754_state *st = iio_priv(indio_dev);
-	int ret;
-
-	ret = spi_w8r16be(st->us, ADE7754_READ_REG(reg_address));
-	if (ret < 0) {
-		dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
-			reg_address);
-		return ret;
-	}
-
-	*val = ret;
-
-	return 0;
-}
-
-static int ade7754_spi_read_reg_24(struct device *dev,
-				   u8 reg_address, u32 *val)
-{
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ade7754_state *st = iio_priv(indio_dev);
-	int ret;
-	struct spi_transfer xfers[] = {
-		{
-			.tx_buf = st->tx,
-			.rx_buf = st->rx,
-			.bits_per_word = 8,
-			.len = 4,
-		},
-	};
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADE7754_READ_REG(reg_address);
-	st->tx[1] = 0;
-	st->tx[2] = 0;
-	st->tx[3] = 0;
-
-	ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
-	if (ret) {
-		dev_err(&st->us->dev, "problem when reading 24 bit register 0x%02X",
-			reg_address);
-		goto error_ret;
-	}
-	*val = (st->rx[1] << 16) | (st->rx[2] << 8) | st->rx[3];
-
-error_ret:
-	mutex_unlock(&st->buf_lock);
-	return ret;
-}
-
-static ssize_t ade7754_read_8bit(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	int ret;
-	u8 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = ade7754_spi_read_reg_8(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	return sprintf(buf, "%u\n", val);
-}
-
-static ssize_t ade7754_read_16bit(struct device *dev,
-				  struct device_attribute *attr,
-				  char *buf)
-{
-	int ret;
-	u16 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = ade7754_spi_read_reg_16(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	return sprintf(buf, "%u\n", val);
-}
-
-static ssize_t ade7754_read_24bit(struct device *dev,
-				  struct device_attribute *attr,
-				  char *buf)
-{
-	int ret;
-	u32 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = ade7754_spi_read_reg_24(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	return sprintf(buf, "%u\n", val & 0xFFFFFF);
-}
-
-static ssize_t ade7754_write_8bit(struct device *dev,
-				  struct device_attribute *attr,
-				  const char *buf,
-				  size_t len)
-{
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-	u8 val;
-
-	ret = kstrtou8(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = ade7754_spi_write_reg_8(dev, this_attr->address, val);
-
-error_ret:
-	return ret ? ret : len;
-}
-
-static ssize_t ade7754_write_16bit(struct device *dev,
-				   struct device_attribute *attr,
-				   const char *buf,
-				   size_t len)
-{
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-	u16 val;
-
-	ret = kstrtou16(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = ade7754_spi_write_reg_16(dev, this_attr->address, val);
-
-error_ret:
-	return ret ? ret : len;
-}
-
-static int ade7754_reset(struct device *dev)
-{
-	int ret;
-	u8 val;
-
-	ret = ade7754_spi_read_reg_8(dev, ADE7754_OPMODE, &val);
-	if (ret < 0)
-		return ret;
-
-	val |= BIT(6); /* Software Chip Reset */
-	return ade7754_spi_write_reg_8(dev, ADE7754_OPMODE, val);
-}
-
-static IIO_DEV_ATTR_AENERGY(ade7754_read_24bit, ADE7754_AENERGY);
-static IIO_DEV_ATTR_LAENERGY(ade7754_read_24bit, ADE7754_LAENERGY);
-static IIO_DEV_ATTR_VAENERGY(ade7754_read_24bit, ADE7754_VAENERGY);
-static IIO_DEV_ATTR_LVAENERGY(ade7754_read_24bit, ADE7754_LVAENERGY);
-static IIO_DEV_ATTR_VPEAK(0644,
-		ade7754_read_8bit,
-		ade7754_write_8bit,
-		ADE7754_VPEAK);
-static IIO_DEV_ATTR_IPEAK(0644,
-		ade7754_read_8bit,
-		ade7754_write_8bit,
-		ADE7754_VPEAK);
-static IIO_DEV_ATTR_APHCAL(0644,
-		ade7754_read_8bit,
-		ade7754_write_8bit,
-		ADE7754_APHCAL);
-static IIO_DEV_ATTR_BPHCAL(0644,
-		ade7754_read_8bit,
-		ade7754_write_8bit,
-		ADE7754_BPHCAL);
-static IIO_DEV_ATTR_CPHCAL(0644,
-		ade7754_read_8bit,
-		ade7754_write_8bit,
-		ADE7754_CPHCAL);
-static IIO_DEV_ATTR_AAPOS(0644,
-		ade7754_read_16bit,
-		ade7754_write_16bit,
-		ADE7754_AAPOS);
-static IIO_DEV_ATTR_BAPOS(0644,
-		ade7754_read_16bit,
-		ade7754_write_16bit,
-		ADE7754_BAPOS);
-static IIO_DEV_ATTR_CAPOS(0644,
-		ade7754_read_16bit,
-		ade7754_write_16bit,
-		ADE7754_CAPOS);
-static IIO_DEV_ATTR_WDIV(0644,
-		ade7754_read_8bit,
-		ade7754_write_8bit,
-		ADE7754_WDIV);
-static IIO_DEV_ATTR_VADIV(0644,
-		ade7754_read_8bit,
-		ade7754_write_8bit,
-		ADE7754_VADIV);
-static IIO_DEV_ATTR_CFNUM(0644,
-		ade7754_read_16bit,
-		ade7754_write_16bit,
-		ADE7754_CFNUM);
-static IIO_DEV_ATTR_CFDEN(0644,
-		ade7754_read_16bit,
-		ade7754_write_16bit,
-		ADE7754_CFDEN);
-static IIO_DEV_ATTR_ACTIVE_POWER_A_GAIN(0644,
-		ade7754_read_16bit,
-		ade7754_write_16bit,
-		ADE7754_AAPGAIN);
-static IIO_DEV_ATTR_ACTIVE_POWER_B_GAIN(0644,
-		ade7754_read_16bit,
-		ade7754_write_16bit,
-		ADE7754_BAPGAIN);
-static IIO_DEV_ATTR_ACTIVE_POWER_C_GAIN(0644,
-		ade7754_read_16bit,
-		ade7754_write_16bit,
-		ADE7754_CAPGAIN);
-static IIO_DEV_ATTR_AIRMS(0444,
-		ade7754_read_24bit,
-		NULL,
-		ADE7754_AIRMS);
-static IIO_DEV_ATTR_BIRMS(0444,
-		ade7754_read_24bit,
-		NULL,
-		ADE7754_BIRMS);
-static IIO_DEV_ATTR_CIRMS(0444,
-		ade7754_read_24bit,
-		NULL,
-		ADE7754_CIRMS);
-static IIO_DEV_ATTR_AVRMS(0444,
-		ade7754_read_24bit,
-		NULL,
-		ADE7754_AVRMS);
-static IIO_DEV_ATTR_BVRMS(0444,
-		ade7754_read_24bit,
-		NULL,
-		ADE7754_BVRMS);
-static IIO_DEV_ATTR_CVRMS(0444,
-		ade7754_read_24bit,
-		NULL,
-		ADE7754_CVRMS);
-static IIO_DEV_ATTR_AIRMSOS(0444,
-		ade7754_read_16bit,
-		ade7754_write_16bit,
-		ADE7754_AIRMSOS);
-static IIO_DEV_ATTR_BIRMSOS(0444,
-		ade7754_read_16bit,
-		ade7754_write_16bit,
-		ADE7754_BIRMSOS);
-static IIO_DEV_ATTR_CIRMSOS(0444,
-		ade7754_read_16bit,
-		ade7754_write_16bit,
-		ADE7754_CIRMSOS);
-static IIO_DEV_ATTR_AVRMSOS(0444,
-		ade7754_read_16bit,
-		ade7754_write_16bit,
-		ADE7754_AVRMSOS);
-static IIO_DEV_ATTR_BVRMSOS(0444,
-		ade7754_read_16bit,
-		ade7754_write_16bit,
-		ADE7754_BVRMSOS);
-static IIO_DEV_ATTR_CVRMSOS(0444,
-		ade7754_read_16bit,
-		ade7754_write_16bit,
-		ADE7754_CVRMSOS);
-
-static int ade7754_set_irq(struct device *dev, bool enable)
-{
-	int ret;
-	u16 irqen;
-
-	ret = ade7754_spi_read_reg_16(dev, ADE7754_IRQEN, &irqen);
-	if (ret)
-		return ret;
-
-	if (enable)
-		irqen |= BIT(14); /* Enables an interrupt when a data is
-				   * present in the waveform register
-				   */
-	else
-		irqen &= ~BIT(14);
-
-	return ade7754_spi_write_reg_16(dev, ADE7754_IRQEN, irqen);
-}
-
-/* Power down the device */
-static int ade7754_stop_device(struct device *dev)
-{
-	int ret;
-	u8 val;
-
-	ret = ade7754_spi_read_reg_8(dev, ADE7754_OPMODE, &val);
-	if (ret < 0) {
-		dev_err(dev, "unable to power down the device, error: %d",
-			ret);
-		return ret;
-	}
-
-	val |= 7 << 3;  /* ADE7754 powered down */
-	return ade7754_spi_write_reg_8(dev, ADE7754_OPMODE, val);
-}
-
-static int ade7754_initial_setup(struct iio_dev *indio_dev)
-{
-	int ret;
-	struct ade7754_state *st = iio_priv(indio_dev);
-	struct device *dev = &indio_dev->dev;
-
-	/* use low spi speed for init */
-	st->us->mode = SPI_MODE_3;
-	spi_setup(st->us);
-
-	/* Disable IRQ */
-	ret = ade7754_set_irq(dev, false);
-	if (ret) {
-		dev_err(dev, "disable irq failed");
-		goto err_ret;
-	}
-
-	ade7754_reset(dev);
-	usleep_range(ADE7754_STARTUP_DELAY, ADE7754_STARTUP_DELAY + 100);
-
-err_ret:
-	return ret;
-}
-
-static ssize_t ade7754_read_frequency(struct device *dev,
-				      struct device_attribute *attr,
-				      char *buf)
-{
-	int ret;
-	u8 t;
-	int sps;
-
-	ret = ade7754_spi_read_reg_8(dev, ADE7754_WAVMODE, &t);
-	if (ret)
-		return ret;
-
-	t = (t >> 3) & 0x3;
-	sps = 26000 / (1 + t);
-
-	return sprintf(buf, "%d\n", sps);
-}
-
-static ssize_t ade7754_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 ade7754_state *st = iio_priv(indio_dev);
-	u16 val;
-	int ret;
-	u8 reg, t;
-
-	ret = kstrtou16(buf, 10, &val);
-	if (ret)
-		return ret;
-	if (!val)
-		return -EINVAL;
-
-	mutex_lock(&st->buf_lock);
-
-	t = 26000 / val;
-	if (t > 0)
-		t--;
-
-	if (t > 1)
-		st->us->max_speed_hz = ADE7754_SPI_SLOW;
-	else
-		st->us->max_speed_hz = ADE7754_SPI_FAST;
-
-	ret = ade7754_spi_read_reg_8(dev, ADE7754_WAVMODE, &reg);
-	if (ret)
-		goto out;
-
-	reg &= ~(3 << 3);
-	reg |= t << 3;
-
-	ret = __ade7754_spi_write_reg_8(dev, ADE7754_WAVMODE, reg);
-
-out:
-	mutex_unlock(&st->buf_lock);
-
-	return ret ? ret : len;
-}
-static IIO_DEV_ATTR_TEMP_RAW(ade7754_read_8bit);
-static IIO_CONST_ATTR(in_temp_offset, "129 C");
-static IIO_CONST_ATTR(in_temp_scale, "4 C");
-
-static IIO_DEV_ATTR_SAMP_FREQ(0644,
-		ade7754_read_frequency,
-		ade7754_write_frequency);
-
-static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("26000 13000 65000 33000");
-
-static struct attribute *ade7754_attributes[] = {
-	&iio_dev_attr_in_temp_raw.dev_attr.attr,
-	&iio_const_attr_in_temp_offset.dev_attr.attr,
-	&iio_const_attr_in_temp_scale.dev_attr.attr,
-	&iio_dev_attr_sampling_frequency.dev_attr.attr,
-	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
-	&iio_dev_attr_aenergy.dev_attr.attr,
-	&iio_dev_attr_laenergy.dev_attr.attr,
-	&iio_dev_attr_vaenergy.dev_attr.attr,
-	&iio_dev_attr_lvaenergy.dev_attr.attr,
-	&iio_dev_attr_vpeak.dev_attr.attr,
-	&iio_dev_attr_ipeak.dev_attr.attr,
-	&iio_dev_attr_aphcal.dev_attr.attr,
-	&iio_dev_attr_bphcal.dev_attr.attr,
-	&iio_dev_attr_cphcal.dev_attr.attr,
-	&iio_dev_attr_aapos.dev_attr.attr,
-	&iio_dev_attr_bapos.dev_attr.attr,
-	&iio_dev_attr_capos.dev_attr.attr,
-	&iio_dev_attr_wdiv.dev_attr.attr,
-	&iio_dev_attr_vadiv.dev_attr.attr,
-	&iio_dev_attr_cfnum.dev_attr.attr,
-	&iio_dev_attr_cfden.dev_attr.attr,
-	&iio_dev_attr_active_power_a_gain.dev_attr.attr,
-	&iio_dev_attr_active_power_b_gain.dev_attr.attr,
-	&iio_dev_attr_active_power_c_gain.dev_attr.attr,
-	&iio_dev_attr_airms.dev_attr.attr,
-	&iio_dev_attr_birms.dev_attr.attr,
-	&iio_dev_attr_cirms.dev_attr.attr,
-	&iio_dev_attr_avrms.dev_attr.attr,
-	&iio_dev_attr_bvrms.dev_attr.attr,
-	&iio_dev_attr_cvrms.dev_attr.attr,
-	&iio_dev_attr_airmsos.dev_attr.attr,
-	&iio_dev_attr_birmsos.dev_attr.attr,
-	&iio_dev_attr_cirmsos.dev_attr.attr,
-	&iio_dev_attr_avrmsos.dev_attr.attr,
-	&iio_dev_attr_bvrmsos.dev_attr.attr,
-	&iio_dev_attr_cvrmsos.dev_attr.attr,
-	NULL,
-};
-
-static const struct attribute_group ade7754_attribute_group = {
-	.attrs = ade7754_attributes,
-};
-
-static const struct iio_info ade7754_info = {
-	.attrs = &ade7754_attribute_group,
-};
-
-static int ade7754_probe(struct spi_device *spi)
-{
-	int ret;
-	struct ade7754_state *st;
-	struct iio_dev *indio_dev;
-
-	/* setup the industrialio driver allocated elements */
-	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
-	if (!indio_dev)
-		return -ENOMEM;
-	/* this is only used for removal purposes */
-	spi_set_drvdata(spi, indio_dev);
-
-	st = iio_priv(indio_dev);
-	st->us = spi;
-	mutex_init(&st->buf_lock);
-
-	indio_dev->name = spi->dev.driver->name;
-	indio_dev->dev.parent = &spi->dev;
-	indio_dev->info = &ade7754_info;
-	indio_dev->modes = INDIO_DIRECT_MODE;
-
-	/* Get the device into a sane initial state */
-	ret = ade7754_initial_setup(indio_dev);
-	if (ret)
-		goto powerdown_on_error;
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto powerdown_on_error;
-	return ret;
-
-powerdown_on_error:
-	ade7754_stop_device(&indio_dev->dev);
-	return ret;
-}
-
-static int ade7754_remove(struct spi_device *spi)
-{
-	struct iio_dev *indio_dev = spi_get_drvdata(spi);
-
-	iio_device_unregister(indio_dev);
-	ade7754_stop_device(&indio_dev->dev);
-
-	return 0;
-}
-
-static struct spi_driver ade7754_driver = {
-	.driver = {
-		.name = "ade7754",
-	},
-	.probe = ade7754_probe,
-	.remove = ade7754_remove,
-};
-module_spi_driver(ade7754_driver);
-
-MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
-MODULE_DESCRIPTION("Analog Devices ADE7754 Polyphase Multifunction Energy Metering IC Driver");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("spi:ad7754");

+ 0 - 183
drivers/staging/iio/meter/ade7758.h

@@ -1,183 +0,0 @@
-/*
- * ADE7758 Poly Phase Multifunction Energy Metering IC driver
- *
- * Copyright 2010-2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2.
- */
-
-#ifndef _ADE7758_H
-#define _ADE7758_H
-
-#define ADE7758_AWATTHR   0x01
-#define ADE7758_BWATTHR   0x02
-#define ADE7758_CWATTHR   0x03
-#define ADE7758_AVARHR    0x04
-#define ADE7758_BVARHR    0x05
-#define ADE7758_CVARHR    0x06
-#define ADE7758_AVAHR     0x07
-#define ADE7758_BVAHR     0x08
-#define ADE7758_CVAHR     0x09
-#define ADE7758_AIRMS     0x0A
-#define ADE7758_BIRMS     0x0B
-#define ADE7758_CIRMS     0x0C
-#define ADE7758_AVRMS     0x0D
-#define ADE7758_BVRMS     0x0E
-#define ADE7758_CVRMS     0x0F
-#define ADE7758_FREQ      0x10
-#define ADE7758_TEMP      0x11
-#define ADE7758_WFORM     0x12
-#define ADE7758_OPMODE    0x13
-#define ADE7758_MMODE     0x14
-#define ADE7758_WAVMODE   0x15
-#define ADE7758_COMPMODE  0x16
-#define ADE7758_LCYCMODE  0x17
-#define ADE7758_MASK      0x18
-#define ADE7758_STATUS    0x19
-#define ADE7758_RSTATUS   0x1A
-#define ADE7758_ZXTOUT    0x1B
-#define ADE7758_LINECYC   0x1C
-#define ADE7758_SAGCYC    0x1D
-#define ADE7758_SAGLVL    0x1E
-#define ADE7758_VPINTLVL  0x1F
-#define ADE7758_IPINTLVL  0x20
-#define ADE7758_VPEAK     0x21
-#define ADE7758_IPEAK     0x22
-#define ADE7758_GAIN      0x23
-#define ADE7758_AVRMSGAIN 0x24
-#define ADE7758_BVRMSGAIN 0x25
-#define ADE7758_CVRMSGAIN 0x26
-#define ADE7758_AIGAIN    0x27
-#define ADE7758_BIGAIN    0x28
-#define ADE7758_CIGAIN    0x29
-#define ADE7758_AWG       0x2A
-#define ADE7758_BWG       0x2B
-#define ADE7758_CWG       0x2C
-#define ADE7758_AVARG     0x2D
-#define ADE7758_BVARG     0x2E
-#define ADE7758_CVARG     0x2F
-#define ADE7758_AVAG      0x30
-#define ADE7758_BVAG      0x31
-#define ADE7758_CVAG      0x32
-#define ADE7758_AVRMSOS   0x33
-#define ADE7758_BVRMSOS   0x34
-#define ADE7758_CVRMSOS   0x35
-#define ADE7758_AIRMSOS   0x36
-#define ADE7758_BIRMSOS   0x37
-#define ADE7758_CIRMSOS   0x38
-#define ADE7758_AWAITOS   0x39
-#define ADE7758_BWAITOS   0x3A
-#define ADE7758_CWAITOS   0x3B
-#define ADE7758_AVAROS    0x3C
-#define ADE7758_BVAROS    0x3D
-#define ADE7758_CVAROS    0x3E
-#define ADE7758_APHCAL    0x3F
-#define ADE7758_BPHCAL    0x40
-#define ADE7758_CPHCAL    0x41
-#define ADE7758_WDIV      0x42
-#define ADE7758_VADIV     0x44
-#define ADE7758_VARDIV    0x43
-#define ADE7758_APCFNUM   0x45
-#define ADE7758_APCFDEN   0x46
-#define ADE7758_VARCFNUM  0x47
-#define ADE7758_VARCFDEN  0x48
-#define ADE7758_CHKSUM    0x7E
-#define ADE7758_VERSION   0x7F
-
-#define ADE7758_READ_REG(a)    a
-#define ADE7758_WRITE_REG(a) ((a) | 0x80)
-
-#define ADE7758_MAX_TX    8
-#define ADE7758_MAX_RX    4
-#define ADE7758_STARTUP_DELAY 1000
-
-#define AD7758_NUM_WAVSEL	5
-#define AD7758_NUM_PHSEL	3
-#define AD7758_NUM_WAVESRC	(AD7758_NUM_WAVSEL * AD7758_NUM_PHSEL)
-
-#define AD7758_PHASE_A		0
-#define AD7758_PHASE_B		1
-#define AD7758_PHASE_C		2
-#define AD7758_CURRENT		0
-#define AD7758_VOLTAGE		1
-#define AD7758_ACT_PWR		2
-#define AD7758_REACT_PWR	3
-#define AD7758_APP_PWR		4
-#define AD7758_WT(p, w)		(((w) << 2) | (p))
-
-/**
- * struct ade7758_state - device instance specific data
- * @us:			actual spi_device
- * @trig:		data ready trigger registered with iio
- * @tx:			transmit buffer
- * @rx:			receive buffer
- * @buf_lock:		mutex to protect tx, rx, read and write frequency
- **/
-struct ade7758_state {
-	struct spi_device	*us;
-	struct iio_trigger	*trig;
-	u8			*tx;
-	u8			*rx;
-	struct mutex		buf_lock;
-	struct spi_transfer	ring_xfer[4];
-	struct spi_message	ring_msg;
-	/*
-	 * DMA (thus cache coherency maintenance) requires the
-	 * transfer buffers to live in their own cache lines.
-	 */
-	unsigned char		rx_buf[8] ____cacheline_aligned;
-	unsigned char		tx_buf[8];
-
-};
-
-#ifdef CONFIG_IIO_BUFFER
-/* At the moment triggers are only used for ring buffer
- * filling. This may change!
- */
-
-void ade7758_remove_trigger(struct iio_dev *indio_dev);
-int ade7758_probe_trigger(struct iio_dev *indio_dev);
-
-ssize_t ade7758_read_data_from_ring(struct device *dev,
-				    struct device_attribute *attr, char *buf);
-
-int ade7758_configure_ring(struct iio_dev *indio_dev);
-void ade7758_unconfigure_ring(struct iio_dev *indio_dev);
-
-int ade7758_set_irq(struct device *dev, bool enable);
-
-int ade7758_spi_write_reg_8(struct device *dev, u8 reg_address, u8 val);
-int ade7758_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val);
-
-#else /* CONFIG_IIO_BUFFER */
-
-static inline void ade7758_remove_trigger(struct iio_dev *indio_dev)
-{
-}
-
-static inline int ade7758_probe_trigger(struct iio_dev *indio_dev)
-{
-	return 0;
-}
-
-static int ade7758_configure_ring(struct iio_dev *indio_dev)
-{
-	return 0;
-}
-
-static inline void ade7758_unconfigure_ring(struct iio_dev *indio_dev)
-{
-}
-
-static inline int ade7758_initialize_ring(struct iio_ring_buffer *ring)
-{
-	return 0;
-}
-
-static inline void ade7758_uninitialize_ring(struct iio_dev *indio_dev)
-{
-}
-
-#endif /* CONFIG_IIO_BUFFER */
-
-#endif

+ 0 - 955
drivers/staging/iio/meter/ade7758_core.c

@@ -1,955 +0,0 @@
-/*
- * ADE7758 Poly Phase Multifunction Energy Metering IC driver
- *
- * Copyright 2010-2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2.
- */
-
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/delay.h>
-#include <linux/mutex.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/list.h>
-#include <linux/module.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-#include <linux/iio/buffer.h>
-#include "meter.h"
-#include "ade7758.h"
-
-static int __ade7758_spi_write_reg_8(struct device *dev, u8 reg_address, u8 val)
-{
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ade7758_state *st = iio_priv(indio_dev);
-
-	st->tx[0] = ADE7758_WRITE_REG(reg_address);
-	st->tx[1] = val;
-
-	return spi_write(st->us, st->tx, 2);
-}
-
-int ade7758_spi_write_reg_8(struct device *dev, u8 reg_address, u8 val)
-{
-	int ret;
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ade7758_state *st = iio_priv(indio_dev);
-
-	mutex_lock(&st->buf_lock);
-	ret = __ade7758_spi_write_reg_8(dev, reg_address, val);
-	mutex_unlock(&st->buf_lock);
-
-	return ret;
-}
-
-static int ade7758_spi_write_reg_16(struct device *dev, u8 reg_address,
-				    u16 value)
-{
-	int ret;
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ade7758_state *st = iio_priv(indio_dev);
-	struct spi_transfer xfers[] = {
-		{
-			.tx_buf = st->tx,
-			.bits_per_word = 8,
-			.len = 3,
-		}
-	};
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADE7758_WRITE_REG(reg_address);
-	st->tx[1] = (value >> 8) & 0xFF;
-	st->tx[2] = value & 0xFF;
-
-	ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
-	mutex_unlock(&st->buf_lock);
-
-	return ret;
-}
-
-static int ade7758_spi_write_reg_24(struct device *dev, u8 reg_address,
-				    u32 value)
-{
-	int ret;
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ade7758_state *st = iio_priv(indio_dev);
-	struct spi_transfer xfers[] = {
-		{
-			.tx_buf = st->tx,
-			.bits_per_word = 8,
-			.len = 4,
-		}
-	};
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADE7758_WRITE_REG(reg_address);
-	st->tx[1] = (value >> 16) & 0xFF;
-	st->tx[2] = (value >> 8) & 0xFF;
-	st->tx[3] = value & 0xFF;
-
-	ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
-	mutex_unlock(&st->buf_lock);
-
-	return ret;
-}
-
-static int __ade7758_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val)
-{
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ade7758_state *st = iio_priv(indio_dev);
-	int ret;
-	struct spi_transfer xfers[] = {
-		{
-			.tx_buf = st->tx,
-			.bits_per_word = 8,
-			.len = 1,
-			.delay_usecs = 4,
-		},
-		{
-			.tx_buf = &st->tx[1],
-			.rx_buf = st->rx,
-			.bits_per_word = 8,
-			.len = 1,
-		},
-	};
-
-	st->tx[0] = ADE7758_READ_REG(reg_address);
-	st->tx[1] = 0;
-
-	ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
-	if (ret) {
-		dev_err(&st->us->dev, "problem when reading 8 bit register 0x%02X",
-			reg_address);
-		goto error_ret;
-	}
-	*val = st->rx[0];
-
-error_ret:
-	return ret;
-}
-
-int ade7758_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val)
-{
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ade7758_state *st = iio_priv(indio_dev);
-	int ret;
-
-	mutex_lock(&st->buf_lock);
-	ret = __ade7758_spi_read_reg_8(dev, reg_address, val);
-	mutex_unlock(&st->buf_lock);
-
-	return ret;
-}
-
-static int ade7758_spi_read_reg_16(struct device *dev, u8 reg_address,
-				   u16 *val)
-{
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ade7758_state *st = iio_priv(indio_dev);
-	int ret;
-	struct spi_transfer xfers[] = {
-		{
-			.tx_buf = st->tx,
-			.bits_per_word = 8,
-			.len = 1,
-			.delay_usecs = 4,
-		},
-		{
-			.tx_buf = &st->tx[1],
-			.rx_buf = st->rx,
-			.bits_per_word = 8,
-			.len = 2,
-		},
-	};
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADE7758_READ_REG(reg_address);
-	st->tx[1] = 0;
-	st->tx[2] = 0;
-
-	ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
-	if (ret) {
-		dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
-			reg_address);
-		goto error_ret;
-	}
-
-	*val = (st->rx[0] << 8) | st->rx[1];
-
-error_ret:
-	mutex_unlock(&st->buf_lock);
-	return ret;
-}
-
-static int ade7758_spi_read_reg_24(struct device *dev, u8 reg_address,
-				   u32 *val)
-{
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ade7758_state *st = iio_priv(indio_dev);
-	int ret;
-	struct spi_transfer xfers[] = {
-		{
-			.tx_buf = st->tx,
-			.bits_per_word = 8,
-			.len = 1,
-			.delay_usecs = 4,
-		},
-		{
-			.tx_buf = &st->tx[1],
-			.rx_buf = st->rx,
-			.bits_per_word = 8,
-			.len = 3,
-		},
-	};
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADE7758_READ_REG(reg_address);
-	st->tx[1] = 0;
-	st->tx[2] = 0;
-	st->tx[3] = 0;
-
-	ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
-	if (ret) {
-		dev_err(&st->us->dev, "problem when reading 24 bit register 0x%02X",
-			reg_address);
-		goto error_ret;
-	}
-	*val = (st->rx[0] << 16) | (st->rx[1] << 8) | st->rx[2];
-
-error_ret:
-	mutex_unlock(&st->buf_lock);
-	return ret;
-}
-
-static ssize_t ade7758_read_8bit(struct device *dev,
-				 struct device_attribute *attr, char *buf)
-{
-	int ret;
-	u8 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = ade7758_spi_read_reg_8(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	return sprintf(buf, "%u\n", val);
-}
-
-static ssize_t ade7758_read_16bit(struct device *dev,
-				  struct device_attribute *attr, char *buf)
-{
-	int ret;
-	u16 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = ade7758_spi_read_reg_16(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	return sprintf(buf, "%u\n", val);
-}
-
-static ssize_t ade7758_read_24bit(struct device *dev,
-				  struct device_attribute *attr, char *buf)
-{
-	int ret;
-	u32 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = ade7758_spi_read_reg_24(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	return sprintf(buf, "%u\n", val & 0xFFFFFF);
-}
-
-static ssize_t ade7758_write_8bit(struct device *dev,
-				  struct device_attribute *attr,
-				  const char *buf, size_t len)
-{
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-	u8 val;
-
-	ret = kstrtou8(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = ade7758_spi_write_reg_8(dev, this_attr->address, val);
-
-error_ret:
-	return ret ? ret : len;
-}
-
-static ssize_t ade7758_write_16bit(struct device *dev,
-				   struct device_attribute *attr,
-				   const char *buf, size_t len)
-{
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-	u16 val;
-
-	ret = kstrtou16(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = ade7758_spi_write_reg_16(dev, this_attr->address, val);
-
-error_ret:
-	return ret ? ret : len;
-}
-
-static int ade7758_reset(struct device *dev)
-{
-	int ret;
-	u8 val;
-
-	ret = ade7758_spi_read_reg_8(dev, ADE7758_OPMODE, &val);
-	if (ret < 0) {
-		dev_err(dev, "Failed to read opmode reg\n");
-		return ret;
-	}
-	val |= BIT(6); /* Software Chip Reset */
-	ret = ade7758_spi_write_reg_8(dev, ADE7758_OPMODE, val);
-	if (ret < 0)
-		dev_err(dev, "Failed to write opmode reg\n");
-	return ret;
-}
-
-static IIO_DEV_ATTR_VPEAK(0644,
-		ade7758_read_8bit,
-		ade7758_write_8bit,
-		ADE7758_VPEAK);
-static IIO_DEV_ATTR_IPEAK(0644,
-		ade7758_read_8bit,
-		ade7758_write_8bit,
-		ADE7758_VPEAK);
-static IIO_DEV_ATTR_APHCAL(0644,
-		ade7758_read_8bit,
-		ade7758_write_8bit,
-		ADE7758_APHCAL);
-static IIO_DEV_ATTR_BPHCAL(0644,
-		ade7758_read_8bit,
-		ade7758_write_8bit,
-		ADE7758_BPHCAL);
-static IIO_DEV_ATTR_CPHCAL(0644,
-		ade7758_read_8bit,
-		ade7758_write_8bit,
-		ADE7758_CPHCAL);
-static IIO_DEV_ATTR_WDIV(0644,
-		ade7758_read_8bit,
-		ade7758_write_8bit,
-		ADE7758_WDIV);
-static IIO_DEV_ATTR_VADIV(0644,
-		ade7758_read_8bit,
-		ade7758_write_8bit,
-		ADE7758_VADIV);
-static IIO_DEV_ATTR_AIRMS(0444,
-		ade7758_read_24bit,
-		NULL,
-		ADE7758_AIRMS);
-static IIO_DEV_ATTR_BIRMS(0444,
-		ade7758_read_24bit,
-		NULL,
-		ADE7758_BIRMS);
-static IIO_DEV_ATTR_CIRMS(0444,
-		ade7758_read_24bit,
-		NULL,
-		ADE7758_CIRMS);
-static IIO_DEV_ATTR_AVRMS(0444,
-		ade7758_read_24bit,
-		NULL,
-		ADE7758_AVRMS);
-static IIO_DEV_ATTR_BVRMS(0444,
-		ade7758_read_24bit,
-		NULL,
-		ADE7758_BVRMS);
-static IIO_DEV_ATTR_CVRMS(0444,
-		ade7758_read_24bit,
-		NULL,
-		ADE7758_CVRMS);
-static IIO_DEV_ATTR_AIRMSOS(0644,
-		ade7758_read_16bit,
-		ade7758_write_16bit,
-		ADE7758_AIRMSOS);
-static IIO_DEV_ATTR_BIRMSOS(0644,
-		ade7758_read_16bit,
-		ade7758_write_16bit,
-		ADE7758_BIRMSOS);
-static IIO_DEV_ATTR_CIRMSOS(0644,
-		ade7758_read_16bit,
-		ade7758_write_16bit,
-		ADE7758_CIRMSOS);
-static IIO_DEV_ATTR_AVRMSOS(0644,
-		ade7758_read_16bit,
-		ade7758_write_16bit,
-		ADE7758_AVRMSOS);
-static IIO_DEV_ATTR_BVRMSOS(0644,
-		ade7758_read_16bit,
-		ade7758_write_16bit,
-		ADE7758_BVRMSOS);
-static IIO_DEV_ATTR_CVRMSOS(0644,
-		ade7758_read_16bit,
-		ade7758_write_16bit,
-		ADE7758_CVRMSOS);
-static IIO_DEV_ATTR_AIGAIN(0644,
-		ade7758_read_16bit,
-		ade7758_write_16bit,
-		ADE7758_AIGAIN);
-static IIO_DEV_ATTR_BIGAIN(0644,
-		ade7758_read_16bit,
-		ade7758_write_16bit,
-		ADE7758_BIGAIN);
-static IIO_DEV_ATTR_CIGAIN(0644,
-		ade7758_read_16bit,
-		ade7758_write_16bit,
-		ADE7758_CIGAIN);
-static IIO_DEV_ATTR_AVRMSGAIN(0644,
-		ade7758_read_16bit,
-		ade7758_write_16bit,
-		ADE7758_AVRMSGAIN);
-static IIO_DEV_ATTR_BVRMSGAIN(0644,
-		ade7758_read_16bit,
-		ade7758_write_16bit,
-		ADE7758_BVRMSGAIN);
-static IIO_DEV_ATTR_CVRMSGAIN(0644,
-		ade7758_read_16bit,
-		ade7758_write_16bit,
-		ADE7758_CVRMSGAIN);
-
-int ade7758_set_irq(struct device *dev, bool enable)
-{
-	int ret;
-	u32 irqen;
-
-	ret = ade7758_spi_read_reg_24(dev, ADE7758_MASK, &irqen);
-	if (ret)
-		return ret;
-
-	if (enable)
-		irqen |= BIT(16); /* Enables an interrupt when a data is
-				   * present in the waveform register
-				   */
-	else
-		irqen &= ~BIT(16);
-
-	ret = ade7758_spi_write_reg_24(dev, ADE7758_MASK, irqen);
-
-	return ret;
-}
-
-/* Power down the device */
-static int ade7758_stop_device(struct device *dev)
-{
-	int ret;
-	u8 val;
-
-	ret = ade7758_spi_read_reg_8(dev, ADE7758_OPMODE, &val);
-	if (ret < 0) {
-		dev_err(dev, "Failed to read opmode reg\n");
-		return ret;
-	}
-	val |= 7 << 3;  /* ADE7758 powered down */
-	ret = ade7758_spi_write_reg_8(dev, ADE7758_OPMODE, val);
-	if (ret < 0)
-		dev_err(dev, "Failed to write opmode reg\n");
-	return ret;
-}
-
-static int ade7758_initial_setup(struct iio_dev *indio_dev)
-{
-	struct ade7758_state *st = iio_priv(indio_dev);
-	struct device *dev = &indio_dev->dev;
-	int ret;
-
-	/* use low spi speed for init */
-	st->us->mode = SPI_MODE_1;
-	spi_setup(st->us);
-
-	/* Disable IRQ */
-	ret = ade7758_set_irq(dev, false);
-	if (ret) {
-		dev_err(dev, "disable irq failed");
-		goto err_ret;
-	}
-
-	ade7758_reset(dev);
-	usleep_range(ADE7758_STARTUP_DELAY, ADE7758_STARTUP_DELAY + 100);
-
-err_ret:
-	return ret;
-}
-
-static int ade7758_read_samp_freq(struct device *dev, int *val)
-{
-	int ret;
-	u8 t;
-
-	ret = ade7758_spi_read_reg_8(dev, ADE7758_WAVMODE, &t);
-	if (ret)
-		return ret;
-
-	t = (t >> 5) & 0x3;
-	*val = 26040 / (1 << t);
-
-	return 0;
-}
-
-static int ade7758_write_samp_freq(struct device *dev, int val)
-{
-	int ret;
-	u8 reg, t;
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ade7758_state *st = iio_priv(indio_dev);
-
-	switch (val) {
-	case 26040:
-		t = 0;
-		break;
-	case 13020:
-		t = 1;
-		break;
-	case 6510:
-		t = 2;
-		break;
-	case 3255:
-		t = 3;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	mutex_lock(&st->buf_lock);
-
-	ret = __ade7758_spi_read_reg_8(dev, ADE7758_WAVMODE, &reg);
-	if (ret)
-		goto out;
-
-	reg &= ~(5 << 3);
-	reg |= t << 5;
-
-	ret = __ade7758_spi_write_reg_8(dev, ADE7758_WAVMODE, reg);
-
-out:
-	mutex_unlock(&st->buf_lock);
-
-	return ret;
-}
-
-static int ade7758_read_raw(struct iio_dev *indio_dev,
-			    struct iio_chan_spec const *chan,
-			    int *val,
-			    int *val2,
-			    long mask)
-{
-	int ret;
-
-	switch (mask) {
-	case IIO_CHAN_INFO_SAMP_FREQ:
-
-		ret = ade7758_read_samp_freq(&indio_dev->dev, val);
-
-		return ret;
-	default:
-		return -EINVAL;
-	}
-
-	return ret;
-}
-
-static int ade7758_write_raw(struct iio_dev *indio_dev,
-			     struct iio_chan_spec const *chan,
-			     int val, int val2, long mask)
-{
-	int ret;
-
-	switch (mask) {
-	case IIO_CHAN_INFO_SAMP_FREQ:
-		if (val2)
-			return -EINVAL;
-
-		ret = ade7758_write_samp_freq(&indio_dev->dev, val);
-
-		return ret;
-	default:
-		return -EINVAL;
-	}
-
-	return ret;
-}
-
-static IIO_DEV_ATTR_TEMP_RAW(ade7758_read_8bit);
-static IIO_CONST_ATTR(in_temp_offset, "129 C");
-static IIO_CONST_ATTR(in_temp_scale, "4 C");
-
-static IIO_DEV_ATTR_AWATTHR(ade7758_read_16bit,
-		ADE7758_AWATTHR);
-static IIO_DEV_ATTR_BWATTHR(ade7758_read_16bit,
-		ADE7758_BWATTHR);
-static IIO_DEV_ATTR_CWATTHR(ade7758_read_16bit,
-		ADE7758_CWATTHR);
-static IIO_DEV_ATTR_AVARHR(ade7758_read_16bit,
-		ADE7758_AVARHR);
-static IIO_DEV_ATTR_BVARHR(ade7758_read_16bit,
-		ADE7758_BVARHR);
-static IIO_DEV_ATTR_CVARHR(ade7758_read_16bit,
-		ADE7758_CVARHR);
-static IIO_DEV_ATTR_AVAHR(ade7758_read_16bit,
-		ADE7758_AVAHR);
-static IIO_DEV_ATTR_BVAHR(ade7758_read_16bit,
-		ADE7758_BVAHR);
-static IIO_DEV_ATTR_CVAHR(ade7758_read_16bit,
-		ADE7758_CVAHR);
-
-static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("26040 13020 6510 3255");
-
-static struct attribute *ade7758_attributes[] = {
-	&iio_dev_attr_in_temp_raw.dev_attr.attr,
-	&iio_const_attr_in_temp_offset.dev_attr.attr,
-	&iio_const_attr_in_temp_scale.dev_attr.attr,
-	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
-	&iio_dev_attr_awatthr.dev_attr.attr,
-	&iio_dev_attr_bwatthr.dev_attr.attr,
-	&iio_dev_attr_cwatthr.dev_attr.attr,
-	&iio_dev_attr_avarhr.dev_attr.attr,
-	&iio_dev_attr_bvarhr.dev_attr.attr,
-	&iio_dev_attr_cvarhr.dev_attr.attr,
-	&iio_dev_attr_avahr.dev_attr.attr,
-	&iio_dev_attr_bvahr.dev_attr.attr,
-	&iio_dev_attr_cvahr.dev_attr.attr,
-	&iio_dev_attr_vpeak.dev_attr.attr,
-	&iio_dev_attr_ipeak.dev_attr.attr,
-	&iio_dev_attr_aphcal.dev_attr.attr,
-	&iio_dev_attr_bphcal.dev_attr.attr,
-	&iio_dev_attr_cphcal.dev_attr.attr,
-	&iio_dev_attr_wdiv.dev_attr.attr,
-	&iio_dev_attr_vadiv.dev_attr.attr,
-	&iio_dev_attr_airms.dev_attr.attr,
-	&iio_dev_attr_birms.dev_attr.attr,
-	&iio_dev_attr_cirms.dev_attr.attr,
-	&iio_dev_attr_avrms.dev_attr.attr,
-	&iio_dev_attr_bvrms.dev_attr.attr,
-	&iio_dev_attr_cvrms.dev_attr.attr,
-	&iio_dev_attr_aigain.dev_attr.attr,
-	&iio_dev_attr_bigain.dev_attr.attr,
-	&iio_dev_attr_cigain.dev_attr.attr,
-	&iio_dev_attr_avrmsgain.dev_attr.attr,
-	&iio_dev_attr_bvrmsgain.dev_attr.attr,
-	&iio_dev_attr_cvrmsgain.dev_attr.attr,
-	&iio_dev_attr_airmsos.dev_attr.attr,
-	&iio_dev_attr_birmsos.dev_attr.attr,
-	&iio_dev_attr_cirmsos.dev_attr.attr,
-	&iio_dev_attr_avrmsos.dev_attr.attr,
-	&iio_dev_attr_bvrmsos.dev_attr.attr,
-	&iio_dev_attr_cvrmsos.dev_attr.attr,
-	NULL,
-};
-
-static const struct attribute_group ade7758_attribute_group = {
-	.attrs = ade7758_attributes,
-};
-
-static const struct iio_chan_spec ade7758_channels[] = {
-	{
-		.type = IIO_VOLTAGE,
-		.indexed = 1,
-		.channel = 0,
-		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
-		.address = AD7758_WT(AD7758_PHASE_A, AD7758_VOLTAGE),
-		.scan_index = 0,
-		.scan_type = {
-			.sign = 's',
-			.realbits = 24,
-			.storagebits = 32,
-		},
-	}, {
-		.type = IIO_CURRENT,
-		.indexed = 1,
-		.channel = 0,
-		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
-		.address = AD7758_WT(AD7758_PHASE_A, AD7758_CURRENT),
-		.scan_index = 1,
-		.scan_type = {
-			.sign = 's',
-			.realbits = 24,
-			.storagebits = 32,
-		},
-	}, {
-		.type = IIO_POWER,
-		.indexed = 1,
-		.channel = 0,
-		.extend_name = "apparent",
-		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
-		.address = AD7758_WT(AD7758_PHASE_A, AD7758_APP_PWR),
-		.scan_index = 2,
-		.scan_type = {
-			.sign = 's',
-			.realbits = 24,
-			.storagebits = 32,
-		},
-	}, {
-		.type = IIO_POWER,
-		.indexed = 1,
-		.channel = 0,
-		.extend_name = "active",
-		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
-		.address = AD7758_WT(AD7758_PHASE_A, AD7758_ACT_PWR),
-		.scan_index = 3,
-		.scan_type = {
-			.sign = 's',
-			.realbits = 24,
-			.storagebits = 32,
-		},
-	}, {
-		.type = IIO_POWER,
-		.indexed = 1,
-		.channel = 0,
-		.extend_name = "reactive",
-		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
-		.address = AD7758_WT(AD7758_PHASE_A, AD7758_REACT_PWR),
-		.scan_index = 4,
-		.scan_type = {
-			.sign = 's',
-			.realbits = 24,
-			.storagebits = 32,
-		},
-	}, {
-		.type = IIO_VOLTAGE,
-		.indexed = 1,
-		.channel = 1,
-		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
-		.address = AD7758_WT(AD7758_PHASE_B, AD7758_VOLTAGE),
-		.scan_index = 5,
-		.scan_type = {
-			.sign = 's',
-			.realbits = 24,
-			.storagebits = 32,
-		},
-	}, {
-		.type = IIO_CURRENT,
-		.indexed = 1,
-		.channel = 1,
-		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
-		.address = AD7758_WT(AD7758_PHASE_B, AD7758_CURRENT),
-		.scan_index = 6,
-		.scan_type = {
-			.sign = 's',
-			.realbits = 24,
-			.storagebits = 32,
-		},
-	}, {
-		.type = IIO_POWER,
-		.indexed = 1,
-		.channel = 1,
-		.extend_name = "apparent",
-		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
-		.address = AD7758_WT(AD7758_PHASE_B, AD7758_APP_PWR),
-		.scan_index = 7,
-		.scan_type = {
-			.sign = 's',
-			.realbits = 24,
-			.storagebits = 32,
-		},
-	}, {
-		.type = IIO_POWER,
-		.indexed = 1,
-		.channel = 1,
-		.extend_name = "active",
-		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
-		.address = AD7758_WT(AD7758_PHASE_B, AD7758_ACT_PWR),
-		.scan_index = 8,
-		.scan_type = {
-			.sign = 's',
-			.realbits = 24,
-			.storagebits = 32,
-		},
-	}, {
-		.type = IIO_POWER,
-		.indexed = 1,
-		.channel = 1,
-		.extend_name = "reactive",
-		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
-		.address = AD7758_WT(AD7758_PHASE_B, AD7758_REACT_PWR),
-		.scan_index = 9,
-		.scan_type = {
-			.sign = 's',
-			.realbits = 24,
-			.storagebits = 32,
-		},
-	}, {
-		.type = IIO_VOLTAGE,
-		.indexed = 1,
-		.channel = 2,
-		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
-		.address = AD7758_WT(AD7758_PHASE_C, AD7758_VOLTAGE),
-		.scan_index = 10,
-		.scan_type = {
-			.sign = 's',
-			.realbits = 24,
-			.storagebits = 32,
-		},
-	}, {
-		.type = IIO_CURRENT,
-		.indexed = 1,
-		.channel = 2,
-		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
-		.address = AD7758_WT(AD7758_PHASE_C, AD7758_CURRENT),
-		.scan_index = 11,
-		.scan_type = {
-			.sign = 's',
-			.realbits = 24,
-			.storagebits = 32,
-		},
-	}, {
-		.type = IIO_POWER,
-		.indexed = 1,
-		.channel = 2,
-		.extend_name = "apparent",
-		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
-		.address = AD7758_WT(AD7758_PHASE_C, AD7758_APP_PWR),
-		.scan_index = 12,
-		.scan_type = {
-			.sign = 's',
-			.realbits = 24,
-			.storagebits = 32,
-		},
-	}, {
-		.type = IIO_POWER,
-		.indexed = 1,
-		.channel = 2,
-		.extend_name = "active",
-		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
-		.address = AD7758_WT(AD7758_PHASE_C, AD7758_ACT_PWR),
-		.scan_index = 13,
-		.scan_type = {
-			.sign = 's',
-			.realbits = 24,
-			.storagebits = 32,
-		},
-	}, {
-		.type = IIO_POWER,
-		.indexed = 1,
-		.channel = 2,
-		.extend_name = "reactive",
-		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
-		.address = AD7758_WT(AD7758_PHASE_C, AD7758_REACT_PWR),
-		.scan_index = 14,
-		.scan_type = {
-			.sign = 's',
-			.realbits = 24,
-			.storagebits = 32,
-		},
-	},
-	IIO_CHAN_SOFT_TIMESTAMP(15),
-};
-
-static const struct iio_info ade7758_info = {
-	.attrs = &ade7758_attribute_group,
-	.read_raw = &ade7758_read_raw,
-	.write_raw = &ade7758_write_raw,
-};
-
-static int ade7758_probe(struct spi_device *spi)
-{
-	int ret;
-	struct ade7758_state *st;
-	struct iio_dev *indio_dev;
-
-	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
-	if (!indio_dev)
-		return -ENOMEM;
-
-	st = iio_priv(indio_dev);
-	/* this is only used for removal purposes */
-	spi_set_drvdata(spi, indio_dev);
-
-	/* Allocate the comms buffers */
-	st->rx = kcalloc(ADE7758_MAX_RX, sizeof(*st->rx), GFP_KERNEL);
-	if (!st->rx)
-		return -ENOMEM;
-	st->tx = kcalloc(ADE7758_MAX_TX, sizeof(*st->tx), GFP_KERNEL);
-	if (!st->tx) {
-		ret = -ENOMEM;
-		goto error_free_rx;
-	}
-	st->us = spi;
-	mutex_init(&st->buf_lock);
-
-	indio_dev->name = spi->dev.driver->name;
-	indio_dev->dev.parent = &spi->dev;
-	indio_dev->info = &ade7758_info;
-	indio_dev->modes = INDIO_DIRECT_MODE;
-	indio_dev->channels = ade7758_channels;
-	indio_dev->num_channels = ARRAY_SIZE(ade7758_channels);
-
-	ret = ade7758_configure_ring(indio_dev);
-	if (ret)
-		goto error_free_tx;
-
-	/* Get the device into a sane initial state */
-	ret = ade7758_initial_setup(indio_dev);
-	if (ret)
-		goto error_unreg_ring_funcs;
-
-	if (spi->irq) {
-		ret = ade7758_probe_trigger(indio_dev);
-		if (ret)
-			goto error_unreg_ring_funcs;
-	}
-
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_remove_trigger;
-
-	return 0;
-
-error_remove_trigger:
-	if (spi->irq)
-		ade7758_remove_trigger(indio_dev);
-error_unreg_ring_funcs:
-	ade7758_unconfigure_ring(indio_dev);
-error_free_tx:
-	kfree(st->tx);
-error_free_rx:
-	kfree(st->rx);
-	return ret;
-}
-
-static int ade7758_remove(struct spi_device *spi)
-{
-	struct iio_dev *indio_dev = spi_get_drvdata(spi);
-	struct ade7758_state *st = iio_priv(indio_dev);
-
-	iio_device_unregister(indio_dev);
-	ade7758_stop_device(&indio_dev->dev);
-	ade7758_remove_trigger(indio_dev);
-	ade7758_unconfigure_ring(indio_dev);
-	kfree(st->tx);
-	kfree(st->rx);
-
-	return 0;
-}
-
-static const struct spi_device_id ade7758_id[] = {
-	{"ade7758", 0},
-	{}
-};
-MODULE_DEVICE_TABLE(spi, ade7758_id);
-
-static struct spi_driver ade7758_driver = {
-	.driver = {
-		.name = "ade7758",
-	},
-	.probe = ade7758_probe,
-	.remove = ade7758_remove,
-	.id_table = ade7758_id,
-};
-module_spi_driver(ade7758_driver);
-
-MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
-MODULE_DESCRIPTION("Analog Devices ADE7758 Polyphase Multifunction Energy Metering IC Driver");
-MODULE_LICENSE("GPL v2");

+ 0 - 177
drivers/staging/iio/meter/ade7758_ring.c

@@ -1,177 +0,0 @@
-/*
- * ADE7758 Poly Phase Multifunction Energy Metering IC driver
- *
- * Copyright 2010-2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2.
- */
-#include <linux/export.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <asm/unaligned.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/buffer.h>
-#include <linux/iio/kfifo_buf.h>
-#include <linux/iio/trigger_consumer.h>
-#include "ade7758.h"
-
-/**
- * ade7758_spi_read_burst() - read data registers
- * @indio_dev: the IIO device
- **/
-static int ade7758_spi_read_burst(struct iio_dev *indio_dev)
-{
-	struct ade7758_state *st = iio_priv(indio_dev);
-	int ret;
-
-	ret = spi_sync(st->us, &st->ring_msg);
-	if (ret)
-		dev_err(&st->us->dev, "problem when reading WFORM value\n");
-
-	return ret;
-}
-
-static int ade7758_write_waveform_type(struct device *dev, unsigned int type)
-{
-	int ret;
-	u8 reg;
-
-	ret = ade7758_spi_read_reg_8(dev, ADE7758_WAVMODE, &reg);
-	if (ret)
-		goto out;
-
-	reg &= ~0x1F;
-	reg |= type & 0x1F;
-
-	ret = ade7758_spi_write_reg_8(dev, ADE7758_WAVMODE, reg);
-out:
-	return ret;
-}
-
-/* Whilst this makes a lot of calls to iio_sw_ring functions - it is too device
- * specific to be rolled into the core.
- */
-static irqreturn_t ade7758_trigger_handler(int irq, void *p)
-{
-	struct iio_poll_func *pf = p;
-	struct iio_dev *indio_dev = pf->indio_dev;
-	struct ade7758_state *st = iio_priv(indio_dev);
-	s64 dat64[2];
-	u32 *dat32 = (u32 *)dat64;
-
-	if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
-		if (ade7758_spi_read_burst(indio_dev) >= 0)
-			*dat32 = get_unaligned_be32(&st->rx_buf[5]) & 0xFFFFFF;
-
-	iio_push_to_buffers_with_timestamp(indio_dev, dat64, pf->timestamp);
-
-	iio_trigger_notify_done(indio_dev->trig);
-
-	return IRQ_HANDLED;
-}
-
-/**
- * ade7758_ring_preenable() setup the parameters of the ring before enabling
- *
- * The complex nature of the setting of the number of bytes per datum is due
- * to this driver currently ensuring that the timestamp is stored at an 8
- * byte boundary.
- **/
-static int ade7758_ring_preenable(struct iio_dev *indio_dev)
-{
-	unsigned int channel;
-
-	if (bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
-		return -EINVAL;
-
-	channel = find_first_bit(indio_dev->active_scan_mask,
-				 indio_dev->masklength);
-
-	ade7758_write_waveform_type(&indio_dev->dev,
-				    indio_dev->channels[channel].address);
-
-	return 0;
-}
-
-static const struct iio_buffer_setup_ops ade7758_ring_setup_ops = {
-	.preenable = &ade7758_ring_preenable,
-	.postenable = &iio_triggered_buffer_postenable,
-	.predisable = &iio_triggered_buffer_predisable,
-	.validate_scan_mask = &iio_validate_scan_mask_onehot,
-};
-
-void ade7758_unconfigure_ring(struct iio_dev *indio_dev)
-{
-	iio_dealloc_pollfunc(indio_dev->pollfunc);
-	iio_kfifo_free(indio_dev->buffer);
-}
-
-int ade7758_configure_ring(struct iio_dev *indio_dev)
-{
-	struct ade7758_state *st = iio_priv(indio_dev);
-	struct iio_buffer *buffer;
-	int ret = 0;
-
-	buffer = iio_kfifo_allocate();
-	if (!buffer)
-		return -ENOMEM;
-
-	iio_device_attach_buffer(indio_dev, buffer);
-
-	indio_dev->setup_ops = &ade7758_ring_setup_ops;
-
-	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
-						 &ade7758_trigger_handler,
-						 0,
-						 indio_dev,
-						 "ade7759_consumer%d",
-						 indio_dev->id);
-	if (!indio_dev->pollfunc) {
-		ret = -ENOMEM;
-		goto error_iio_kfifo_free;
-	}
-
-	indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
-
-	st->tx_buf[0] = ADE7758_READ_REG(ADE7758_RSTATUS);
-	st->tx_buf[1] = 0;
-	st->tx_buf[2] = 0;
-	st->tx_buf[3] = 0;
-	st->tx_buf[4] = ADE7758_READ_REG(ADE7758_WFORM);
-	st->tx_buf[5] = 0;
-	st->tx_buf[6] = 0;
-	st->tx_buf[7] = 0;
-
-	/* build spi ring message */
-	st->ring_xfer[0].tx_buf = &st->tx_buf[0];
-	st->ring_xfer[0].len = 1;
-	st->ring_xfer[0].bits_per_word = 8;
-	st->ring_xfer[0].delay_usecs = 4;
-	st->ring_xfer[1].rx_buf = &st->rx_buf[1];
-	st->ring_xfer[1].len = 3;
-	st->ring_xfer[1].bits_per_word = 8;
-	st->ring_xfer[1].cs_change = 1;
-
-	st->ring_xfer[2].tx_buf = &st->tx_buf[4];
-	st->ring_xfer[2].len = 1;
-	st->ring_xfer[2].bits_per_word = 8;
-	st->ring_xfer[2].delay_usecs = 1;
-	st->ring_xfer[3].rx_buf = &st->rx_buf[5];
-	st->ring_xfer[3].len = 3;
-	st->ring_xfer[3].bits_per_word = 8;
-
-	spi_message_init(&st->ring_msg);
-	spi_message_add_tail(&st->ring_xfer[0], &st->ring_msg);
-	spi_message_add_tail(&st->ring_xfer[1], &st->ring_msg);
-	spi_message_add_tail(&st->ring_xfer[2], &st->ring_msg);
-	spi_message_add_tail(&st->ring_xfer[3], &st->ring_msg);
-
-	return 0;
-
-error_iio_kfifo_free:
-	iio_kfifo_free(indio_dev->buffer);
-	return ret;
-}

+ 0 - 108
drivers/staging/iio/meter/ade7758_trigger.c

@@ -1,108 +0,0 @@
-/*
- * ADE7758 Poly Phase Multifunction Energy Metering IC driver
- *
- * Copyright 2010-2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2.
- */
-
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/export.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/trigger.h>
-#include "ade7758.h"
-
-/**
- * ade7758_data_rdy_trig_poll() the event handler for the data rdy trig
- **/
-static irqreturn_t ade7758_data_rdy_trig_poll(int irq, void *private)
-{
-	disable_irq_nosync(irq);
-	iio_trigger_poll(private);
-
-	return IRQ_HANDLED;
-}
-
-/**
- * ade7758_data_rdy_trigger_set_state() set datardy interrupt state
- **/
-static int ade7758_data_rdy_trigger_set_state(struct iio_trigger *trig,
-					      bool state)
-{
-	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
-
-	dev_dbg(&indio_dev->dev, "(%d)\n", state);
-	return ade7758_set_irq(&indio_dev->dev, state);
-}
-
-/**
- * ade7758_trig_try_reen() try renabling irq for data rdy trigger
- * @trig:	the datardy trigger
- **/
-static int ade7758_trig_try_reen(struct iio_trigger *trig)
-{
-	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
-	struct ade7758_state *st = iio_priv(indio_dev);
-
-	enable_irq(st->us->irq);
-	/* irq reenabled so success! */
-	return 0;
-}
-
-static const struct iio_trigger_ops ade7758_trigger_ops = {
-	.set_trigger_state = &ade7758_data_rdy_trigger_set_state,
-	.try_reenable = &ade7758_trig_try_reen,
-};
-
-int ade7758_probe_trigger(struct iio_dev *indio_dev)
-{
-	struct ade7758_state *st = iio_priv(indio_dev);
-	int ret;
-
-	st->trig = iio_trigger_alloc("%s-dev%d",
-				     spi_get_device_id(st->us)->name,
-				     indio_dev->id);
-	if (!st->trig) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
-
-	ret = request_irq(st->us->irq,
-			  ade7758_data_rdy_trig_poll,
-			  IRQF_TRIGGER_LOW,
-			  spi_get_device_id(st->us)->name,
-			  st->trig);
-	if (ret)
-		goto error_free_trig;
-
-	st->trig->dev.parent = &st->us->dev;
-	st->trig->ops = &ade7758_trigger_ops;
-	iio_trigger_set_drvdata(st->trig, indio_dev);
-	ret = iio_trigger_register(st->trig);
-
-	/* select default trigger */
-	indio_dev->trig = iio_trigger_get(st->trig);
-	if (ret)
-		goto error_free_irq;
-
-	return 0;
-
-error_free_irq:
-	free_irq(st->us->irq, st->trig);
-error_free_trig:
-	iio_trigger_free(st->trig);
-error_ret:
-	return ret;
-}
-
-void ade7758_remove_trigger(struct iio_dev *indio_dev)
-{
-	struct ade7758_state *st = iio_priv(indio_dev);
-
-	iio_trigger_unregister(st->trig);
-	free_irq(st->us->irq, st->trig);
-	iio_trigger_free(st->trig);
-}

+ 0 - 558
drivers/staging/iio/meter/ade7759.c

@@ -1,558 +0,0 @@
-/*
- * ADE7759 Active Energy Metering IC with di/dt Sensor Interface Driver
- *
- * Copyright 2010 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/delay.h>
-#include <linux/mutex.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/list.h>
-#include <linux/module.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-#include "meter.h"
-
-#define ADE7759_WAVEFORM  0x01
-#define ADE7759_AENERGY   0x02
-#define ADE7759_RSTENERGY 0x03
-#define ADE7759_STATUS    0x04
-#define ADE7759_RSTSTATUS 0x05
-#define ADE7759_MODE      0x06
-#define ADE7759_CFDEN     0x07
-#define ADE7759_CH1OS     0x08
-#define ADE7759_CH2OS     0x09
-#define ADE7759_GAIN      0x0A
-#define ADE7759_APGAIN    0x0B
-#define ADE7759_PHCAL     0x0C
-#define ADE7759_APOS      0x0D
-#define ADE7759_ZXTOUT    0x0E
-#define ADE7759_SAGCYC    0x0F
-#define ADE7759_IRQEN     0x10
-#define ADE7759_SAGLVL    0x11
-#define ADE7759_TEMP      0x12
-#define ADE7759_LINECYC   0x13
-#define ADE7759_LENERGY   0x14
-#define ADE7759_CFNUM     0x15
-#define ADE7759_CHKSUM    0x1E
-#define ADE7759_DIEREV    0x1F
-
-#define ADE7759_READ_REG(a)    a
-#define ADE7759_WRITE_REG(a) ((a) | 0x80)
-
-#define ADE7759_MAX_TX    6
-#define ADE7759_MAX_RX    6
-#define ADE7759_STARTUP_DELAY 1000
-
-#define ADE7759_SPI_SLOW	(u32)(300 * 1000)
-#define ADE7759_SPI_BURST	(u32)(1000 * 1000)
-#define ADE7759_SPI_FAST	(u32)(2000 * 1000)
-
-/**
- * struct ade7759_state - device instance specific data
- * @us:			actual spi_device
- * @buf_lock:		mutex to protect tx and rx and write frequency
- * @tx:			transmit buffer
- * @rx:			receive buffer
- **/
-struct ade7759_state {
-	struct spi_device	*us;
-	struct mutex		buf_lock;
-	u8			tx[ADE7759_MAX_TX] ____cacheline_aligned;
-	u8			rx[ADE7759_MAX_RX];
-};
-
-static int ade7759_spi_write_reg_8(struct device *dev,
-				   u8 reg_address,
-				   u8 val)
-{
-	int ret;
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ade7759_state *st = iio_priv(indio_dev);
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADE7759_WRITE_REG(reg_address);
-	st->tx[1] = val;
-
-	ret = spi_write(st->us, st->tx, 2);
-	mutex_unlock(&st->buf_lock);
-
-	return ret;
-}
-
-/*Unlocked version of ade7759_spi_write_reg_16 function */
-static int __ade7759_spi_write_reg_16(struct device *dev,
-				      u8 reg_address,
-				      u16 value)
-{
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ade7759_state *st = iio_priv(indio_dev);
-
-	st->tx[0] = ADE7759_WRITE_REG(reg_address);
-	st->tx[1] = (value >> 8) & 0xFF;
-	st->tx[2] = value & 0xFF;
-	return spi_write(st->us, st->tx, 3);
-}
-
-static int ade7759_spi_write_reg_16(struct device *dev,
-				    u8 reg_address,
-				    u16 value)
-{
-	int ret;
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ade7759_state *st = iio_priv(indio_dev);
-
-	mutex_lock(&st->buf_lock);
-	ret = __ade7759_spi_write_reg_16(dev, reg_address, value);
-	mutex_unlock(&st->buf_lock);
-
-	return ret;
-}
-
-static int ade7759_spi_read_reg_8(struct device *dev,
-				  u8 reg_address,
-				  u8 *val)
-{
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ade7759_state *st = iio_priv(indio_dev);
-	int ret;
-
-	ret = spi_w8r8(st->us, ADE7759_READ_REG(reg_address));
-	if (ret < 0) {
-		dev_err(&st->us->dev,
-			"problem when reading 8 bit register 0x%02X",
-			reg_address);
-		return ret;
-	}
-	*val = ret;
-
-	return 0;
-}
-
-static int ade7759_spi_read_reg_16(struct device *dev,
-				   u8 reg_address,
-				   u16 *val)
-{
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ade7759_state *st = iio_priv(indio_dev);
-	int ret;
-
-	ret = spi_w8r16be(st->us, ADE7759_READ_REG(reg_address));
-	if (ret < 0) {
-		dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
-			reg_address);
-		return ret;
-	}
-
-	*val = ret;
-
-	return 0;
-}
-
-static int ade7759_spi_read_reg_40(struct device *dev,
-				   u8 reg_address,
-				   u64 *val)
-{
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ade7759_state *st = iio_priv(indio_dev);
-	int ret;
-	struct spi_transfer xfers[] = {
-		{
-			.tx_buf = st->tx,
-			.rx_buf = st->rx,
-			.bits_per_word = 8,
-			.len = 6,
-		},
-	};
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADE7759_READ_REG(reg_address);
-	memset(&st->tx[1], 0, 5);
-
-	ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
-	if (ret) {
-		dev_err(&st->us->dev,
-			"problem when reading 40 bit register 0x%02X",
-			reg_address);
-		goto error_ret;
-	}
-	*val = ((u64)st->rx[1] << 32) | ((u64)st->rx[2] << 24) |
-		(st->rx[3] << 16) | (st->rx[4] << 8) | st->rx[5];
-
-error_ret:
-	mutex_unlock(&st->buf_lock);
-	return ret;
-}
-
-static ssize_t ade7759_read_8bit(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	int ret;
-	u8 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = ade7759_spi_read_reg_8(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	return sprintf(buf, "%u\n", val);
-}
-
-static ssize_t ade7759_read_16bit(struct device *dev,
-				  struct device_attribute *attr,
-				  char *buf)
-{
-	int ret;
-	u16 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = ade7759_spi_read_reg_16(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	return sprintf(buf, "%u\n", val);
-}
-
-static ssize_t ade7759_read_40bit(struct device *dev,
-				  struct device_attribute *attr,
-				  char *buf)
-{
-	int ret;
-	u64 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = ade7759_spi_read_reg_40(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	return sprintf(buf, "%llu\n", val);
-}
-
-static ssize_t ade7759_write_8bit(struct device *dev,
-				  struct device_attribute *attr,
-				  const char *buf,
-				  size_t len)
-{
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-	u8 val;
-
-	ret = kstrtou8(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = ade7759_spi_write_reg_8(dev, this_attr->address, val);
-
-error_ret:
-	return ret ? ret : len;
-}
-
-static ssize_t ade7759_write_16bit(struct device *dev,
-				   struct device_attribute *attr,
-				   const char *buf,
-				   size_t len)
-{
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-	u16 val;
-
-	ret = kstrtou16(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = ade7759_spi_write_reg_16(dev, this_attr->address, val);
-
-error_ret:
-	return ret ? ret : len;
-}
-
-static int ade7759_reset(struct device *dev)
-{
-	int ret;
-	u16 val;
-
-	ret = ade7759_spi_read_reg_16(dev, ADE7759_MODE, &val);
-	if (ret < 0)
-		return ret;
-
-	val |= BIT(6); /* Software Chip Reset */
-	return ade7759_spi_write_reg_16(dev,
-			ADE7759_MODE,
-			val);
-}
-
-static IIO_DEV_ATTR_AENERGY(ade7759_read_40bit, ADE7759_AENERGY);
-static IIO_DEV_ATTR_CFDEN(0644,
-		ade7759_read_16bit,
-		ade7759_write_16bit,
-		ADE7759_CFDEN);
-static IIO_DEV_ATTR_CFNUM(0644,
-		ade7759_read_8bit,
-		ade7759_write_8bit,
-		ADE7759_CFNUM);
-static IIO_DEV_ATTR_CHKSUM(ade7759_read_8bit, ADE7759_CHKSUM);
-static IIO_DEV_ATTR_PHCAL(0644,
-		ade7759_read_16bit,
-		ade7759_write_16bit,
-		ADE7759_PHCAL);
-static IIO_DEV_ATTR_APOS(0644,
-		ade7759_read_16bit,
-		ade7759_write_16bit,
-		ADE7759_APOS);
-static IIO_DEV_ATTR_SAGCYC(0644,
-		ade7759_read_8bit,
-		ade7759_write_8bit,
-		ADE7759_SAGCYC);
-static IIO_DEV_ATTR_SAGLVL(0644,
-		ade7759_read_8bit,
-		ade7759_write_8bit,
-		ADE7759_SAGLVL);
-static IIO_DEV_ATTR_LINECYC(0644,
-		ade7759_read_8bit,
-		ade7759_write_8bit,
-		ADE7759_LINECYC);
-static IIO_DEV_ATTR_LENERGY(ade7759_read_40bit, ADE7759_LENERGY);
-static IIO_DEV_ATTR_PGA_GAIN(0644,
-		ade7759_read_8bit,
-		ade7759_write_8bit,
-		ADE7759_GAIN);
-static IIO_DEV_ATTR_ACTIVE_POWER_GAIN(0644,
-		ade7759_read_16bit,
-		ade7759_write_16bit,
-		ADE7759_APGAIN);
-
-static IIO_DEVICE_ATTR(choff_1, 0644,
-			ade7759_read_8bit,
-			ade7759_write_8bit,
-			ADE7759_CH1OS);
-
-static IIO_DEVICE_ATTR(choff_2, 0644,
-			ade7759_read_8bit,
-			ade7759_write_8bit,
-			ADE7759_CH2OS);
-
-static int ade7759_set_irq(struct device *dev, bool enable)
-{
-	int ret;
-	u8 irqen;
-
-	ret = ade7759_spi_read_reg_8(dev, ADE7759_IRQEN, &irqen);
-	if (ret)
-		goto error_ret;
-
-	if (enable)
-		irqen |= BIT(3); /* Enables an interrupt when a data is
-				  * present in the waveform register
-				  */
-	else
-		irqen &= ~BIT(3);
-
-	ret = ade7759_spi_write_reg_8(dev, ADE7759_IRQEN, irqen);
-
-error_ret:
-	return ret;
-}
-
-/* Power down the device */
-static int ade7759_stop_device(struct device *dev)
-{
-	int ret;
-	u16 val;
-
-	ret = ade7759_spi_read_reg_16(dev, ADE7759_MODE, &val);
-	if (ret < 0) {
-		dev_err(dev, "unable to power down the device, error: %d\n",
-			ret);
-		return ret;
-	}
-
-	val |= BIT(4);  /* AD converters can be turned off */
-
-	return ade7759_spi_write_reg_16(dev, ADE7759_MODE, val);
-}
-
-static int ade7759_initial_setup(struct iio_dev *indio_dev)
-{
-	int ret;
-	struct ade7759_state *st = iio_priv(indio_dev);
-	struct device *dev = &indio_dev->dev;
-
-	/* use low spi speed for init */
-	st->us->mode = SPI_MODE_3;
-	spi_setup(st->us);
-
-	/* Disable IRQ */
-	ret = ade7759_set_irq(dev, false);
-	if (ret) {
-		dev_err(dev, "disable irq failed");
-		goto err_ret;
-	}
-
-	ade7759_reset(dev);
-	usleep_range(ADE7759_STARTUP_DELAY, ADE7759_STARTUP_DELAY + 100);
-
-err_ret:
-	return ret;
-}
-
-static ssize_t ade7759_read_frequency(struct device *dev,
-				      struct device_attribute *attr,
-				      char *buf)
-{
-	int ret;
-	u16 t;
-	int sps;
-
-	ret = ade7759_spi_read_reg_16(dev, ADE7759_MODE, &t);
-	if (ret)
-		return ret;
-
-	t = (t >> 3) & 0x3;
-	sps = 27900 / (1 + t);
-
-	return sprintf(buf, "%d\n", sps);
-}
-
-static ssize_t ade7759_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 ade7759_state *st = iio_priv(indio_dev);
-	u16 val;
-	int ret;
-	u16 reg, t;
-
-	ret = kstrtou16(buf, 10, &val);
-	if (ret)
-		return ret;
-	if (!val)
-		return -EINVAL;
-
-	mutex_lock(&st->buf_lock);
-
-	t = 27900 / val;
-	if (t > 0)
-		t--;
-
-	if (t > 1)
-		st->us->max_speed_hz = ADE7759_SPI_SLOW;
-	else
-		st->us->max_speed_hz = ADE7759_SPI_FAST;
-
-	ret = ade7759_spi_read_reg_16(dev, ADE7759_MODE, &reg);
-	if (ret)
-		goto out;
-
-	reg &= ~(3 << 13);
-	reg |= t << 13;
-
-	ret = __ade7759_spi_write_reg_16(dev, ADE7759_MODE, reg);
-
-out:
-	mutex_unlock(&st->buf_lock);
-
-	return ret ? ret : len;
-}
-static IIO_DEV_ATTR_TEMP_RAW(ade7759_read_8bit);
-static IIO_CONST_ATTR(in_temp_offset, "70 C");
-static IIO_CONST_ATTR(in_temp_scale, "1 C");
-
-static IIO_DEV_ATTR_SAMP_FREQ(0644,
-		ade7759_read_frequency,
-		ade7759_write_frequency);
-
-static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("27900 14000 7000 3500");
-
-static struct attribute *ade7759_attributes[] = {
-	&iio_dev_attr_in_temp_raw.dev_attr.attr,
-	&iio_const_attr_in_temp_offset.dev_attr.attr,
-	&iio_const_attr_in_temp_scale.dev_attr.attr,
-	&iio_dev_attr_sampling_frequency.dev_attr.attr,
-	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
-	&iio_dev_attr_phcal.dev_attr.attr,
-	&iio_dev_attr_cfden.dev_attr.attr,
-	&iio_dev_attr_aenergy.dev_attr.attr,
-	&iio_dev_attr_cfnum.dev_attr.attr,
-	&iio_dev_attr_apos.dev_attr.attr,
-	&iio_dev_attr_sagcyc.dev_attr.attr,
-	&iio_dev_attr_saglvl.dev_attr.attr,
-	&iio_dev_attr_linecyc.dev_attr.attr,
-	&iio_dev_attr_lenergy.dev_attr.attr,
-	&iio_dev_attr_chksum.dev_attr.attr,
-	&iio_dev_attr_pga_gain.dev_attr.attr,
-	&iio_dev_attr_active_power_gain.dev_attr.attr,
-	&iio_dev_attr_choff_1.dev_attr.attr,
-	&iio_dev_attr_choff_2.dev_attr.attr,
-	NULL,
-};
-
-static const struct attribute_group ade7759_attribute_group = {
-	.attrs = ade7759_attributes,
-};
-
-static const struct iio_info ade7759_info = {
-	.attrs = &ade7759_attribute_group,
-};
-
-static int ade7759_probe(struct spi_device *spi)
-{
-	int ret;
-	struct ade7759_state *st;
-	struct iio_dev *indio_dev;
-
-	/* setup the industrialio driver allocated elements */
-	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
-	if (!indio_dev)
-		return -ENOMEM;
-	/* this is only used for removal purposes */
-	spi_set_drvdata(spi, indio_dev);
-
-	st = iio_priv(indio_dev);
-	st->us = spi;
-	mutex_init(&st->buf_lock);
-	indio_dev->name = spi->dev.driver->name;
-	indio_dev->dev.parent = &spi->dev;
-	indio_dev->info = &ade7759_info;
-	indio_dev->modes = INDIO_DIRECT_MODE;
-
-	/* Get the device into a sane initial state */
-	ret = ade7759_initial_setup(indio_dev);
-	if (ret)
-		return ret;
-
-	return iio_device_register(indio_dev);
-}
-
-static int ade7759_remove(struct spi_device *spi)
-{
-	struct iio_dev *indio_dev = spi_get_drvdata(spi);
-
-	iio_device_unregister(indio_dev);
-	ade7759_stop_device(&indio_dev->dev);
-
-	return 0;
-}
-
-static struct spi_driver ade7759_driver = {
-	.driver = {
-		.name = "ade7759",
-	},
-	.probe = ade7759_probe,
-	.remove = ade7759_remove,
-};
-module_spi_driver(ade7759_driver);
-
-MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
-MODULE_DESCRIPTION("Analog Devices ADE7759 Active Energy Metering IC Driver");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("spi:ad7759");

+ 0 - 12
drivers/staging/iio/resolver/Kconfig

@@ -13,18 +13,6 @@ config AD2S90
 	  To compile this driver as a module, choose M here: the
 	  module will be called ad2s90.
 
-config AD2S1200
-	tristate "Analog Devices ad2s1200/ad2s1205 driver"
-	depends on SPI
-	depends on GPIOLIB || COMPILE_TEST
-	help
-	  Say yes here to build support for Analog Devices spi resolver
-	  to digital converters, ad2s1200 and ad2s1205, provides direct access
-	  via sysfs.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called ad2s1200.
-
 config AD2S1210
 	tristate "Analog Devices ad2s1210 driver"
 	depends on SPI

+ 0 - 1
drivers/staging/iio/resolver/Makefile

@@ -3,5 +3,4 @@
 #
 
 obj-$(CONFIG_AD2S90) += ad2s90.o
-obj-$(CONFIG_AD2S1200) += ad2s1200.o
 obj-$(CONFIG_AD2S1210) += ad2s1210.o

+ 2 - 0
include/linux/iio/adc/stm32-dfsdm-adc.h

@@ -9,6 +9,8 @@
 #ifndef STM32_DFSDM_ADC_H
 #define STM32_DFSDM_ADC_H
 
+#include <linux/iio/iio.h>
+
 int stm32_dfsdm_get_buff_cb(struct iio_dev *iio_dev,
 			    int (*cb)(const void *data, size_t size,
 				      void *private),

+ 25 - 26
drivers/staging/iio/light/tsl2x7x.h → include/linux/platform_data/tsl2772.h

@@ -1,51 +1,51 @@
 /* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Device driver for monitoring ambient light intensity (lux)
- * and proximity (prox) within the TAOS TSL2X7X family of devices.
+ * and proximity (prox) within the TAOS TSL2772 family of devices.
  *
  * Copyright (c) 2012, TAOS Corporation.
+ * Copyright (c) 2017-2018 Brian Masney <masneyb@onstation.org>
  */
 
-#ifndef __TSL2X7X_H
-#define __TSL2X7X_H
+#ifndef __TSL2772_H
+#define __TSL2772_H
 
-struct tsl2x7x_lux {
+struct tsl2772_lux {
 	unsigned int ch0;
 	unsigned int ch1;
 };
 
 /* Max number of segments allowable in LUX table */
-#define TSL2X7X_MAX_LUX_TABLE_SIZE		6
+#define TSL2772_MAX_LUX_TABLE_SIZE		6
 /* The default LUX tables all have 3 elements.  */
-#define TSL2X7X_DEF_LUX_TABLE_SZ		3
-#define TSL2X7X_DEFAULT_TABLE_BYTES (sizeof(struct tsl2x7x_lux) * \
-				     TSL2X7X_DEF_LUX_TABLE_SZ)
+#define TSL2772_DEF_LUX_TABLE_SZ		3
+#define TSL2772_DEFAULT_TABLE_BYTES (sizeof(struct tsl2772_lux) * \
+				     TSL2772_DEF_LUX_TABLE_SZ)
 
 /* Proximity diode to use */
-#define TSL2X7X_DIODE0                  0x01
-#define TSL2X7X_DIODE1                  0x02
-#define TSL2X7X_DIODE_BOTH              0x03
+#define TSL2772_DIODE0                  0x01
+#define TSL2772_DIODE1                  0x02
+#define TSL2772_DIODE_BOTH              0x03
 
 /* LED Power */
-#define TSL2X7X_100_mA                  0x00
-#define TSL2X7X_50_mA                   0x01
-#define TSL2X7X_25_mA                   0x02
-#define TSL2X7X_13_mA                   0x03
-#define TSL2X7X_MAX_TIMER_CNT           0xFF
+#define TSL2772_100_mA                  0x00
+#define TSL2772_50_mA                   0x01
+#define TSL2772_25_mA                   0x02
+#define TSL2772_13_mA                   0x03
 
 /**
- * struct tsl2x7x_settings - Settings for the tsl2x7x driver
+ * struct tsl2772_settings - Settings for the tsl2772 driver
  *  @als_time:              Integration time of the ALS channel ADCs in 2.73 ms
  *                          increments. Total integration time is
  *                          (256 - als_time) * 2.73.
- *  @als_gain:              Index into the tsl2x7x_als_gain array.
+ *  @als_gain:              Index into the tsl2772_als_gain array.
  *  @als_gain_trim:         Default gain trim to account for aperture effects.
  *  @wait_time:             Time between proximity and ALS cycles in 2.73
  *                          periods.
  *  @prox_time:             Integration time of the proximity ADC in 2.73 ms
  *                          increments. Total integration time is
  *                          (256 - prx_time) * 2.73.
- *  @prox_gain:             Index into the tsl2x7x_prx_gain array.
+ *  @prox_gain:             Index into the tsl2772_prx_gain array.
  *  @als_prox_config:       The value of the ALS / Proximity configuration
  *                          register.
  *  @als_cal_target:        Known external ALS reading for calibration.
@@ -65,7 +65,7 @@ struct tsl2x7x_lux {
  *                          LED(s) for proximity sensing.
  *  @prox_power             The amount of power to use for the external LED(s).
  */
-struct tsl2x7x_settings {
+struct tsl2772_settings {
 	int als_time;
 	int als_gain;
 	int als_gain_trim;
@@ -89,14 +89,13 @@ struct tsl2x7x_settings {
 };
 
 /**
- * struct tsl2X7X_platform_data - Platform callback, glass and defaults
+ * struct tsl2772_platform_data - Platform callback, glass and defaults
  * @platform_lux_table:        Device specific glass coefficents
  * @platform_default_settings: Device specific power on defaults
- *
  */
-struct tsl2X7X_platform_data {
-	struct tsl2x7x_lux platform_lux_table[TSL2X7X_MAX_LUX_TABLE_SIZE];
-	struct tsl2x7x_settings *platform_default_settings;
+struct tsl2772_platform_data {
+	struct tsl2772_lux platform_lux_table[TSL2772_MAX_LUX_TABLE_SIZE];
+	struct tsl2772_settings *platform_default_settings;
 };
 
-#endif /* __TSL2X7X_H */
+#endif /* __TSL2772_H */

+ 8 - 5
tools/iio/iio_generic_buffer.c

@@ -248,7 +248,7 @@ void print_usage(void)
 		"Capture, convert and output data from IIO device buffer\n"
 		"  -a         Auto-activate all available channels\n"
 		"  -A         Force-activate ALL channels\n"
-		"  -c <n>     Do n conversions\n"
+		"  -c <n>     Do n conversions, or loop forever if n < 0\n"
 		"  -e         Disable wait for event (new data)\n"
 		"  -g         Use trigger-less mode\n"
 		"  -l <n>     Set buffer length to n samples\n"
@@ -330,11 +330,14 @@ static const struct option longopts[] = {
 
 int main(int argc, char **argv)
 {
-	unsigned long num_loops = 2;
+	unsigned long long num_loops = 2;
 	unsigned long timedelay = 1000000;
 	unsigned long buf_len = 128;
 
-	int ret, c, i, j, toread;
+	ssize_t i;
+	unsigned long long j;
+	unsigned long toread;
+	int ret, c;
 	int fp = -1;
 
 	int num_channels = 0;
@@ -366,7 +369,7 @@ int main(int argc, char **argv)
 			break;	
 		case 'c':
 			errno = 0;
-			num_loops = strtoul(optarg, &dummy, 10);
+			num_loops = strtoll(optarg, &dummy, 10);
 			if (errno) {
 				ret = -errno;
 				goto error;
@@ -634,7 +637,7 @@ int main(int argc, char **argv)
 		goto error;
 	}
 
-	for (j = 0; j < num_loops; j++) {
+	for (j = 0; j < num_loops || num_loops < 0; j++) {
 		if (!noevents) {
 			struct pollfd pfd = {
 				.fd = fp,