summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/iio/Kconfig14
-rw-r--r--drivers/iio/Makefile2
-rw-r--r--drivers/iio/accel/Kconfig20
-rw-r--r--drivers/iio/accel/Makefile4
-rw-r--r--drivers/iio/accel/hid-sensor-accel-3d.c35
-rw-r--r--drivers/iio/accel/kxsd9.c17
-rw-r--r--drivers/iio/accel/st_accel.h11
-rw-r--r--drivers/iio/accel/st_accel_core.c28
-rw-r--r--drivers/iio/accel/st_accel_i2c.c17
-rw-r--r--drivers/iio/accel/st_accel_spi.c17
-rw-r--r--drivers/iio/adc/Kconfig47
-rw-r--r--drivers/iio/adc/Makefile2
-rw-r--r--drivers/iio/adc/ad7266.c16
-rw-r--r--drivers/iio/adc/ad7298.c24
-rw-r--r--drivers/iio/adc/ad7476.c26
-rw-r--r--drivers/iio/adc/ad7791.c19
-rw-r--r--drivers/iio/adc/ad7793.c23
-rw-r--r--drivers/iio/adc/ad7887.c23
-rw-r--r--drivers/iio/adc/ad7923.c20
-rw-r--r--drivers/iio/adc/at91_adc.c23
-rw-r--r--drivers/iio/adc/exynos_adc.c23
-rw-r--r--drivers/iio/adc/lp8788_adc.c7
-rw-r--r--drivers/iio/adc/max1363.c15
-rw-r--r--drivers/iio/adc/mcp320x.c18
-rw-r--r--drivers/iio/adc/nau7802.c581
-rw-r--r--drivers/iio/adc/ti-adc081c.c18
-rw-r--r--drivers/iio/adc/ti_am335x_adc.c13
-rw-r--r--drivers/iio/adc/viperboard_adc.c9
-rw-r--r--drivers/iio/amplifiers/Kconfig2
-rw-r--r--drivers/iio/amplifiers/Makefile1
-rw-r--r--drivers/iio/amplifiers/ad8366.c13
-rw-r--r--drivers/iio/common/Makefile1
-rw-r--r--drivers/iio/common/st_sensors/st_sensors_core.c41
-rw-r--r--drivers/iio/dac/Kconfig44
-rw-r--r--drivers/iio/dac/Makefile1
-rw-r--r--drivers/iio/dac/mcp4725.c177
-rw-r--r--drivers/iio/frequency/Kconfig1
-rw-r--r--drivers/iio/frequency/Makefile1
-rw-r--r--drivers/iio/frequency/ad9523.c17
-rw-r--r--drivers/iio/frequency/adf4350.c31
-rw-r--r--drivers/iio/gyro/Kconfig18
-rw-r--r--drivers/iio/gyro/Makefile2
-rw-r--r--drivers/iio/gyro/adis16260.c (renamed from drivers/staging/iio/gyro/adis16260_core.c)305
-rw-r--r--drivers/iio/gyro/hid-sensor-gyro-3d.c16
-rw-r--r--drivers/iio/gyro/st_gyro.h11
-rw-r--r--drivers/iio/gyro/st_gyro_core.c13
-rw-r--r--drivers/iio/gyro/st_gyro_i2c.c3
-rw-r--r--drivers/iio/gyro/st_gyro_spi.c3
-rw-r--r--drivers/iio/iio_core_trigger.h7
-rw-r--r--drivers/iio/imu/Kconfig2
-rw-r--r--drivers/iio/imu/Makefile1
-rw-r--r--drivers/iio/imu/adis16400_core.c10
-rw-r--r--drivers/iio/imu/adis16480.c10
-rw-r--r--drivers/iio/imu/inv_mpu6050/inv_mpu_core.c29
-rw-r--r--drivers/iio/industrialio-core.c51
-rw-r--r--drivers/iio/light/Kconfig34
-rw-r--r--drivers/iio/light/Makefile4
-rw-r--r--drivers/iio/light/adjd_s311.c15
-rw-r--r--drivers/iio/light/apds9300.c512
-rw-r--r--drivers/iio/light/hid-sensor-als.c33
-rw-r--r--drivers/iio/light/lm3533-als.c7
-rw-r--r--drivers/iio/light/tsl2563.c25
-rw-r--r--drivers/iio/light/vcnl4000.c16
-rw-r--r--drivers/iio/magnetometer/Kconfig6
-rw-r--r--drivers/iio/magnetometer/Makefile1
-rw-r--r--drivers/iio/magnetometer/hid-sensor-magn-3d.c35
-rw-r--r--drivers/iio/magnetometer/st_magn.h3
-rw-r--r--drivers/iio/magnetometer/st_magn_core.c6
-rw-r--r--drivers/iio/magnetometer/st_magn_i2c.c17
-rw-r--r--drivers/iio/magnetometer/st_magn_spi.c17
-rw-r--r--drivers/iio/pressure/Kconfig14
-rw-r--r--drivers/iio/pressure/Makefile1
-rw-r--r--drivers/iio/pressure/st_pressure.h11
-rw-r--r--drivers/iio/pressure/st_pressure_core.c21
-rw-r--r--drivers/iio/pressure/st_pressure_i2c.c17
-rw-r--r--drivers/iio/pressure/st_pressure_spi.c17
-rw-r--r--drivers/iio/trigger/Kconfig4
-rw-r--r--drivers/iio/trigger/Makefile1
-rw-r--r--drivers/staging/iio/Documentation/device.txt4
-rw-r--r--drivers/staging/iio/adc/mxs-lradc.c33
-rw-r--r--drivers/staging/iio/adc/spear_adc.c30
-rw-r--r--drivers/staging/iio/addac/adt7316.c27
-rw-r--r--drivers/staging/iio/gyro/Kconfig12
-rw-r--r--drivers/staging/iio/gyro/Makefile3
-rw-r--r--drivers/staging/iio/gyro/adis16260.h98
-rw-r--r--drivers/staging/iio/gyro/adis16260_platform_data.h19
-rw-r--r--drivers/staging/iio/light/isl29018.c16
-rw-r--r--drivers/staging/iio/light/isl29028.c13
-rw-r--r--drivers/staging/iio/magnetometer/hmc5843.c71
-rw-r--r--drivers/staging/iio/meter/ade7753.c18
-rw-r--r--drivers/staging/iio/meter/ade7754.c19
-rw-r--r--drivers/staging/iio/meter/ade7758_core.c18
-rw-r--r--drivers/staging/iio/meter/ade7758_ring.c2
-rw-r--r--drivers/staging/iio/meter/ade7759.c18
-rw-r--r--drivers/staging/iio/meter/ade7854.c19
-rw-r--r--drivers/staging/iio/resolver/ad2s1210.c18
96 files changed, 2011 insertions, 1127 deletions
diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig
index 9af763a90d93..b682f6f54501 100644
--- a/drivers/iio/Kconfig
+++ b/drivers/iio/Kconfig
@@ -12,6 +12,13 @@ menuconfig IIO
if IIO
+config IIO_DEBUG
+ boolean "Debug support for Industrial I/O"
+ depends on DEBUG_KERNEL
+ help
+ Say "yes" to enable debug messaging (like dev_dbg and pr_debug)
+ support in Industrial I/O subsystem and drivers.
+
config IIO_BUFFER
bool "Enable buffer support within IIO"
help
@@ -23,15 +30,14 @@ if IIO_BUFFER
config IIO_BUFFER_CB
boolean "IIO callback buffer used for push in-kernel interfaces"
help
- Should be selected by any drivers that do-inkernel push
+ Should be selected by any drivers that do in-kernel push
usage. That is, those where the data is pushed to the consumer.
config IIO_KFIFO_BUF
select IIO_TRIGGER
tristate "Industrial I/O buffering based on kfifo"
help
- A simple fifo based on kfifo. Use this if you want a fifo
- rather than a ring buffer. Note that this currently provides
+ A simple fifo based on kfifo. Note that this currently provides
no buffer events so it is up to userspace to work out how
often to read from the buffer.
@@ -49,7 +55,7 @@ config IIO_TRIGGER
help
Provides IIO core support for triggers. Currently these
are used to initialize capture of samples to push into
- ring buffers. The triggers are effectively a 'capture
+ buffers. The triggers are effectively a 'capture
data now' interrupt.
config IIO_CONSUMERS_PER_TRIGGER
diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile
index 7a3866c2d2a1..6e43e5b8d4ed 100644
--- a/drivers/iio/Makefile
+++ b/drivers/iio/Makefile
@@ -2,6 +2,8 @@
# Makefile for the industrial I/O core.
#
+ccflags-$(CONFIG_IIO_DEBUG) := -DDEBUG
+
obj-$(CONFIG_IIO) += industrialio.o
industrialio-y := industrialio-core.o industrialio-event.o inkern.o
industrialio-$(CONFIG_IIO_BUFFER) += industrialio-buffer.o
diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 719d83fe51dd..61ca7ec0f3e7 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -1,6 +1,8 @@
#
# Accelerometer drivers
#
+# When adding new entries keep the list in alphabetical order
+
menu "Accelerometers"
config HID_SENSOR_ACCEL_3D
@@ -14,13 +16,6 @@ config HID_SENSOR_ACCEL_3D
Say yes here to build support for the HID SENSOR
accelerometers 3D.
-config KXSD9
- tristate "Kionix KXSD9 Accelerometer Driver"
- depends on SPI
- help
- Say yes here to build support for the Kionix KXSD9 accelerometer.
- Currently this only supports the device via an SPI interface.
-
config IIO_ST_ACCEL_3AXIS
tristate "STMicroelectronics accelerometers 3-Axis Driver"
depends on (I2C || SPI_MASTER) && SYSFS
@@ -33,8 +28,8 @@ config IIO_ST_ACCEL_3AXIS
LSM303DLH, LSM303DLHC, LIS3DH, LSM330D, LSM330DL, LSM330DLC,
LIS331DLH, LSM303DL, LSM303DLM, LSM330.
- This driver can also be built as a module. If so, will be created
- these modules:
+ This driver can also be built as a module. If so, these modules
+ will be created:
- st_accel (core functions for the driver [it is mandatory]);
- st_accel_i2c (necessary for the I2C devices [optional*]);
- st_accel_spi (necessary for the SPI devices [optional*]);
@@ -51,4 +46,11 @@ config IIO_ST_ACCEL_SPI_3AXIS
depends on IIO_ST_ACCEL_3AXIS
depends on IIO_ST_SENSORS_SPI
+config KXSD9
+ tristate "Kionix KXSD9 Accelerometer Driver"
+ depends on SPI
+ help
+ Say yes here to build support for the Kionix KXSD9 accelerometer.
+ Currently this only supports the device via an SPI interface.
+
endmenu
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index 87d8fa264894..2f95a3dffa47 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -2,7 +2,9 @@
# Makefile for industrial I/O accelerometer drivers
#
+# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
+obj-$(CONFIG_KXSD9) += kxsd9.o
obj-$(CONFIG_IIO_ST_ACCEL_3AXIS) += st_accel.o
st_accel-y := st_accel_core.o
@@ -10,5 +12,3 @@ st_accel-$(CONFIG_IIO_BUFFER) += st_accel_buffer.o
obj-$(CONFIG_IIO_ST_ACCEL_I2C_3AXIS) += st_accel_i2c.o
obj-$(CONFIG_IIO_ST_ACCEL_SPI_3AXIS) += st_accel_spi.o
-
-obj-$(CONFIG_KXSD9) += kxsd9.o
diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c
index bbcbd7101f33..68df3416b612 100644
--- a/drivers/iio/accel/hid-sensor-accel-3d.c
+++ b/drivers/iio/accel/hid-sensor-accel-3d.c
@@ -30,10 +30,6 @@
#include <linux/iio/triggered_buffer.h>
#include "../common/hid-sensors/hid-sensor-trigger.h"
-/*Format: HID-SENSOR-usage_id_in_hex*/
-/*Usage ID from spec for Accelerometer-3D: 0x200073*/
-#define DRIVER_NAME "HID-SENSOR-200073"
-
enum accel_3d_channel {
CHANNEL_SCAN_INDEX_X,
CHANNEL_SCAN_INDEX_Y,
@@ -286,11 +282,11 @@ static int hid_accel_3d_probe(struct platform_device *pdev)
struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
struct iio_chan_spec *channels;
- indio_dev = iio_device_alloc(sizeof(struct accel_3d_state));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ indio_dev = devm_iio_device_alloc(&pdev->dev,
+ sizeof(struct accel_3d_state));
+ if (indio_dev == NULL)
+ return -ENOMEM;
+
platform_set_drvdata(pdev, indio_dev);
accel_state = iio_priv(indio_dev);
@@ -302,15 +298,14 @@ static int hid_accel_3d_probe(struct platform_device *pdev)
&accel_state->common_attributes);
if (ret) {
dev_err(&pdev->dev, "failed to setup common attributes\n");
- goto error_free_dev;
+ return ret;
}
channels = kmemdup(accel_3d_channels, sizeof(accel_3d_channels),
GFP_KERNEL);
if (!channels) {
- ret = -ENOMEM;
dev_err(&pdev->dev, "failed to duplicate channels\n");
- goto error_free_dev;
+ return -ENOMEM;
}
ret = accel_3d_parse_report(pdev, hsdev, channels,
@@ -367,9 +362,6 @@ error_unreg_buffer_funcs:
iio_triggered_buffer_cleanup(indio_dev);
error_free_dev_mem:
kfree(indio_dev->channels);
-error_free_dev:
- iio_device_free(indio_dev);
-error_ret:
return ret;
}
@@ -384,14 +376,23 @@ static int hid_accel_3d_remove(struct platform_device *pdev)
hid_sensor_remove_trigger(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
kfree(indio_dev->channels);
- iio_device_free(indio_dev);
return 0;
}
+static struct platform_device_id hid_accel_3d_ids[] = {
+ {
+ /* Format: HID-SENSOR-usage_id_in_hex_lowercase */
+ .name = "HID-SENSOR-200073",
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, hid_accel_3d_ids);
+
static struct platform_driver hid_accel_3d_platform_driver = {
+ .id_table = hid_accel_3d_ids,
.driver = {
- .name = DRIVER_NAME,
+ .name = KBUILD_MODNAME,
.owner = THIS_MODULE,
},
.probe = hid_accel_3d_probe,
diff --git a/drivers/iio/accel/kxsd9.c b/drivers/iio/accel/kxsd9.c
index 7229645bf1d7..709c13259f14 100644
--- a/drivers/iio/accel/kxsd9.c
+++ b/drivers/iio/accel/kxsd9.c
@@ -224,11 +224,10 @@ static int kxsd9_probe(struct spi_device *spi)
struct kxsd9_state *st;
int ret;
- indio_dev = iio_device_alloc(sizeof(*st));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (!indio_dev)
+ return -ENOMEM;
+
st = iio_priv(indio_dev);
spi_set_drvdata(spi, indio_dev);
@@ -247,20 +246,14 @@ static int kxsd9_probe(struct spi_device *spi)
ret = iio_device_register(indio_dev);
if (ret)
- goto error_free_dev;
+ return ret;
return 0;
-
-error_free_dev:
- iio_device_free(indio_dev);
-error_ret:
- return ret;
}
static int kxsd9_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
- iio_device_free(spi_get_drvdata(spi));
return 0;
}
diff --git a/drivers/iio/accel/st_accel.h b/drivers/iio/accel/st_accel.h
index 37949b94377d..c3877630b2e4 100644
--- a/drivers/iio/accel/st_accel.h
+++ b/drivers/iio/accel/st_accel.h
@@ -25,7 +25,16 @@
#define LSM303DLM_ACCEL_DEV_NAME "lsm303dlm_accel"
#define LSM330_ACCEL_DEV_NAME "lsm330_accel"
-int st_accel_common_probe(struct iio_dev *indio_dev);
+/**
+* struct st_sensors_platform_data - default accel platform data
+* @drdy_int_pin: default accel DRDY is available on INT1 pin.
+*/
+static const struct st_sensors_platform_data default_accel_pdata = {
+ .drdy_int_pin = 1,
+};
+
+int st_accel_common_probe(struct iio_dev *indio_dev,
+ struct st_sensors_platform_data *pdata);
void st_accel_common_remove(struct iio_dev *indio_dev);
#ifdef CONFIG_IIO_BUFFER
diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c
index 4aec121261d7..1458343f6f3f 100644
--- a/drivers/iio/accel/st_accel_core.c
+++ b/drivers/iio/accel/st_accel_core.c
@@ -65,7 +65,8 @@
#define ST_ACCEL_1_BDU_ADDR 0x23
#define ST_ACCEL_1_BDU_MASK 0x80
#define ST_ACCEL_1_DRDY_IRQ_ADDR 0x22
-#define ST_ACCEL_1_DRDY_IRQ_MASK 0x10
+#define ST_ACCEL_1_DRDY_IRQ_INT1_MASK 0x10
+#define ST_ACCEL_1_DRDY_IRQ_INT2_MASK 0x08
#define ST_ACCEL_1_MULTIREAD_BIT true
/* CUSTOM VALUES FOR SENSOR 2 */
@@ -89,7 +90,8 @@
#define ST_ACCEL_2_BDU_ADDR 0x23
#define ST_ACCEL_2_BDU_MASK 0x80
#define ST_ACCEL_2_DRDY_IRQ_ADDR 0x22
-#define ST_ACCEL_2_DRDY_IRQ_MASK 0x02
+#define ST_ACCEL_2_DRDY_IRQ_INT1_MASK 0x02
+#define ST_ACCEL_2_DRDY_IRQ_INT2_MASK 0x10
#define ST_ACCEL_2_MULTIREAD_BIT true
/* CUSTOM VALUES FOR SENSOR 3 */
@@ -121,7 +123,8 @@
#define ST_ACCEL_3_BDU_ADDR 0x20
#define ST_ACCEL_3_BDU_MASK 0x08
#define ST_ACCEL_3_DRDY_IRQ_ADDR 0x23
-#define ST_ACCEL_3_DRDY_IRQ_MASK 0x80
+#define ST_ACCEL_3_DRDY_IRQ_INT1_MASK 0x80
+#define ST_ACCEL_3_DRDY_IRQ_INT2_MASK 0x00
#define ST_ACCEL_3_IG1_EN_ADDR 0x23
#define ST_ACCEL_3_IG1_EN_MASK 0x08
#define ST_ACCEL_3_MULTIREAD_BIT false
@@ -224,7 +227,8 @@ static const struct st_sensors st_accel_sensors[] = {
},
.drdy_irq = {
.addr = ST_ACCEL_1_DRDY_IRQ_ADDR,
- .mask = ST_ACCEL_1_DRDY_IRQ_MASK,
+ .mask_int1 = ST_ACCEL_1_DRDY_IRQ_INT1_MASK,
+ .mask_int2 = ST_ACCEL_1_DRDY_IRQ_INT2_MASK,
},
.multi_read_bit = ST_ACCEL_1_MULTIREAD_BIT,
.bootime = 2,
@@ -285,7 +289,8 @@ static const struct st_sensors st_accel_sensors[] = {
},
.drdy_irq = {
.addr = ST_ACCEL_2_DRDY_IRQ_ADDR,
- .mask = ST_ACCEL_2_DRDY_IRQ_MASK,
+ .mask_int1 = ST_ACCEL_2_DRDY_IRQ_INT1_MASK,
+ .mask_int2 = ST_ACCEL_2_DRDY_IRQ_INT2_MASK,
},
.multi_read_bit = ST_ACCEL_2_MULTIREAD_BIT,
.bootime = 2,
@@ -358,7 +363,8 @@ static const struct st_sensors st_accel_sensors[] = {
},
.drdy_irq = {
.addr = ST_ACCEL_3_DRDY_IRQ_ADDR,
- .mask = ST_ACCEL_3_DRDY_IRQ_MASK,
+ .mask_int1 = ST_ACCEL_3_DRDY_IRQ_INT1_MASK,
+ .mask_int2 = ST_ACCEL_3_DRDY_IRQ_INT2_MASK,
.ig1 = {
.en_addr = ST_ACCEL_3_IG1_EN_ADDR,
.en_mask = ST_ACCEL_3_IG1_EN_MASK,
@@ -443,7 +449,8 @@ static const struct iio_trigger_ops st_accel_trigger_ops = {
#define ST_ACCEL_TRIGGER_OPS NULL
#endif
-int st_accel_common_probe(struct iio_dev *indio_dev)
+int st_accel_common_probe(struct iio_dev *indio_dev,
+ struct st_sensors_platform_data *plat_data)
{
int err;
struct st_sensor_data *adata = iio_priv(indio_dev);
@@ -465,7 +472,11 @@ int st_accel_common_probe(struct iio_dev *indio_dev)
&adata->sensor->fs.fs_avl[0];
adata->odr = adata->sensor->odr.odr_avl[0].hz;
- err = st_sensors_init_sensor(indio_dev);
+ if (!plat_data)
+ plat_data =
+ (struct st_sensors_platform_data *)&default_accel_pdata;
+
+ err = st_sensors_init_sensor(indio_dev, plat_data);
if (err < 0)
goto st_accel_common_probe_error;
@@ -506,7 +517,6 @@ void st_accel_common_remove(struct iio_dev *indio_dev)
st_sensors_deallocate_trigger(indio_dev);
st_accel_deallocate_ring(indio_dev);
}
- iio_device_free(indio_dev);
}
EXPORT_SYMBOL(st_accel_common_remove);
diff --git a/drivers/iio/accel/st_accel_i2c.c b/drivers/iio/accel/st_accel_i2c.c
index ffc9d097e484..d7bedbdfc81d 100644
--- a/drivers/iio/accel/st_accel_i2c.c
+++ b/drivers/iio/accel/st_accel_i2c.c
@@ -25,27 +25,20 @@ static int st_accel_i2c_probe(struct i2c_client *client,
struct st_sensor_data *adata;
int err;
- indio_dev = iio_device_alloc(sizeof(*adata));
- if (indio_dev == NULL) {
- err = -ENOMEM;
- goto iio_device_alloc_error;
- }
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*adata));
+ if (!indio_dev)
+ return -ENOMEM;
adata = iio_priv(indio_dev);
adata->dev = &client->dev;
st_sensors_i2c_configure(indio_dev, client, adata);
- err = st_accel_common_probe(indio_dev);
+ err = st_accel_common_probe(indio_dev, client->dev.platform_data);
if (err < 0)
- goto st_accel_common_probe_error;
+ return err;
return 0;
-
-st_accel_common_probe_error:
- iio_device_free(indio_dev);
-iio_device_alloc_error:
- return err;
}
static int st_accel_i2c_remove(struct i2c_client *client)
diff --git a/drivers/iio/accel/st_accel_spi.c b/drivers/iio/accel/st_accel_spi.c
index 22b35bfea7d2..195639646e34 100644
--- a/drivers/iio/accel/st_accel_spi.c
+++ b/drivers/iio/accel/st_accel_spi.c
@@ -24,27 +24,20 @@ static int st_accel_spi_probe(struct spi_device *spi)
struct st_sensor_data *adata;
int err;
- indio_dev = iio_device_alloc(sizeof(*adata));
- if (indio_dev == NULL) {
- err = -ENOMEM;
- goto iio_device_alloc_error;
- }
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adata));
+ if (!indio_dev)
+ return -ENOMEM;
adata = iio_priv(indio_dev);
adata->dev = &spi->dev;
st_sensors_spi_configure(indio_dev, spi, adata);
- err = st_accel_common_probe(indio_dev);
+ err = st_accel_common_probe(indio_dev, spi->dev.platform_data);
if (err < 0)
- goto st_accel_common_probe_error;
+ return err;
return 0;
-
-st_accel_common_probe_error:
- iio_device_free(indio_dev);
-iio_device_alloc_error:
- return err;
}
static int st_accel_spi_remove(struct spi_device *spi)
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 93129ec4b649..f725b4581f04 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -1,6 +1,8 @@
#
# ADC drivers
#
+# When adding new entries keep the list in alphabetical order
+
menu "Analog to digital converters"
config AD_SIGMA_DELTA
@@ -30,17 +32,20 @@ config AD7298
To compile this driver as a module, choose M here: the
module will be called ad7298.
-config AD7923
- tristate "Analog Devices AD7923 and similar ADCs driver"
+config AD7476
+ tristate "Analog Devices AD7476 and similar 1-channel ADCs driver"
depends on SPI
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
- Say yes here to build support for Analog Devices
- AD7904, AD7914, AD7923, AD7924 4 Channel ADCs.
+ Say yes here to build support for Analog Devices AD7273, AD7274, AD7276,
+ AD7277, AD7278, AD7475, AD7476, AD7477, AD7478, AD7466, AD7467, AD7468,
+ AD7495, AD7910, AD7920, AD7920 SPI analog to digital converters (ADC).
+
+ If unsure, say N (but it's safe to say "Y").
To compile this driver as a module, choose M here: the
- module will be called ad7923.
+ module will be called ad7476.
config AD7791
tristate "Analog Devices AD7791 ADC driver"
@@ -66,33 +71,30 @@ config AD7793
To compile this driver as a module, choose M here: the
module will be called AD7793.
-config AD7476
- tristate "Analog Devices AD7476 and similar 1-channel ADCs driver"
+config AD7887
+ tristate "Analog Devices AD7887 ADC driver"
depends on SPI
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
- Say yes here to build support for Analog Devices AD7273, AD7274, AD7276,
- AD7277, AD7278, AD7475, AD7476, AD7477, AD7478, AD7466, AD7467, AD7468,
- AD7495, AD7910, AD7920, AD7920 SPI analog to digital converters (ADC).
-
+ Say yes here to build support for Analog Devices
+ AD7887 SPI analog to digital converter (ADC).
If unsure, say N (but it's safe to say "Y").
To compile this driver as a module, choose M here: the
- module will be called ad7476.
+ module will be called ad7887.
-config AD7887
- tristate "Analog Devices AD7887 ADC driver"
+config AD7923
+ tristate "Analog Devices AD7923 and similar ADCs driver"
depends on SPI
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
Say yes here to build support for Analog Devices
- AD7887 SPI analog to digital converter (ADC).
- If unsure, say N (but it's safe to say "Y").
+ AD7904, AD7914, AD7923, AD7924 4 Channel ADCs.
To compile this driver as a module, choose M here: the
- module will be called ad7887.
+ module will be called ad7923.
config AT91_ADC
tristate "Atmel AT91 ADC"
@@ -143,6 +145,15 @@ config MCP320X
This driver can also be built as a module. If so, the module will be
called mcp320x.
+config NAU7802
+ tristate "Nuvoton NAU7802 ADC driver"
+ depends on I2C
+ help
+ Say yes here to build support for Nuvoton NAU7802 ADC.
+
+ To compile this driver as a module, choose M here: the
+ module will be called nau7802.
+
config TI_ADC081C
tristate "Texas Instruments ADC081C021/027"
depends on I2C
@@ -154,7 +165,7 @@ config TI_ADC081C
called ti-adc081c.
config TI_AM335X_ADC
- tristate "TI's ADC driver"
+ tristate "TI's AM335X ADC driver"
depends on MFD_TI_AM335X_TSCADC
help
Say yes here to build support for Texas Instruments ADC
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 8f475d31fe4d..2a4324ec7f14 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -2,6 +2,7 @@
# Makefile for IIO ADC drivers
#
+# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o
obj-$(CONFIG_AD7266) += ad7266.o
obj-$(CONFIG_AD7298) += ad7298.o
@@ -15,6 +16,7 @@ obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
obj-$(CONFIG_MAX1363) += max1363.o
obj-$(CONFIG_MCP320X) += mcp320x.o
+obj-$(CONFIG_NAU7802) += nau7802.o
obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
diff --git a/drivers/iio/adc/ad7266.c b/drivers/iio/adc/ad7266.c
index c2744a75c3b0..371731df1634 100644
--- a/drivers/iio/adc/ad7266.c
+++ b/drivers/iio/adc/ad7266.c
@@ -399,17 +399,17 @@ static int ad7266_probe(struct spi_device *spi)
unsigned int i;
int ret;
- indio_dev = iio_device_alloc(sizeof(*st));
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
st = iio_priv(indio_dev);
- st->reg = regulator_get(&spi->dev, "vref");
+ st->reg = devm_regulator_get(&spi->dev, "vref");
if (!IS_ERR_OR_NULL(st->reg)) {
ret = regulator_enable(st->reg);
if (ret)
- goto error_put_reg;
+ return ret;
ret = regulator_get_voltage(st->reg);
if (ret < 0)
@@ -489,11 +489,6 @@ error_free_gpios:
error_disable_reg:
if (!IS_ERR_OR_NULL(st->reg))
regulator_disable(st->reg);
-error_put_reg:
- if (!IS_ERR_OR_NULL(st->reg))
- regulator_put(st->reg);
-
- iio_device_free(indio_dev);
return ret;
}
@@ -507,11 +502,8 @@ static int ad7266_remove(struct spi_device *spi)
iio_triggered_buffer_cleanup(indio_dev);
if (!st->fixed_addr)
gpio_free_array(st->gpios, ARRAY_SIZE(st->gpios));
- if (!IS_ERR_OR_NULL(st->reg)) {
+ if (!IS_ERR_OR_NULL(st->reg))
regulator_disable(st->reg);
- regulator_put(st->reg);
- }
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/iio/adc/ad7298.c b/drivers/iio/adc/ad7298.c
index 03b77189dbfe..85d1481c312f 100644
--- a/drivers/iio/adc/ad7298.c
+++ b/drivers/iio/adc/ad7298.c
@@ -296,9 +296,10 @@ static int ad7298_probe(struct spi_device *spi)
{
struct ad7298_platform_data *pdata = spi->dev.platform_data;
struct ad7298_state *st;
- struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
+ struct iio_dev *indio_dev;
int ret;
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
@@ -308,14 +309,13 @@ static int ad7298_probe(struct spi_device *spi)
st->ext_ref = AD7298_EXTREF;
if (st->ext_ref) {
- st->reg = regulator_get(&spi->dev, "vref");
- if (IS_ERR(st->reg)) {
- ret = PTR_ERR(st->reg);
- goto error_free;
- }
+ st->reg = devm_regulator_get(&spi->dev, "vref");
+ if (IS_ERR(st->reg))
+ return PTR_ERR(st->reg);
+
ret = regulator_enable(st->reg);
if (ret)
- goto error_put_reg;
+ return ret;
}
spi_set_drvdata(spi, indio_dev);
@@ -361,11 +361,6 @@ error_cleanup_ring:
error_disable_reg:
if (st->ext_ref)
regulator_disable(st->reg);
-error_put_reg:
- if (st->ext_ref)
- regulator_put(st->reg);
-error_free:
- iio_device_free(indio_dev);
return ret;
}
@@ -377,11 +372,8 @@ static int ad7298_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
- if (st->ext_ref) {
+ if (st->ext_ref)
regulator_disable(st->reg);
- regulator_put(st->reg);
- }
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/iio/adc/ad7476.c b/drivers/iio/adc/ad7476.c
index 2e98bef4af67..6d2b1d8d1a1f 100644
--- a/drivers/iio/adc/ad7476.c
+++ b/drivers/iio/adc/ad7476.c
@@ -213,24 +213,21 @@ static int ad7476_probe(struct spi_device *spi)
struct iio_dev *indio_dev;
int ret;
- indio_dev = iio_device_alloc(sizeof(*st));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (!indio_dev)
+ return -ENOMEM;
+
st = iio_priv(indio_dev);
st->chip_info =
&ad7476_chip_info_tbl[spi_get_device_id(spi)->driver_data];
- st->reg = regulator_get(&spi->dev, "vcc");
- if (IS_ERR(st->reg)) {
- ret = PTR_ERR(st->reg);
- goto error_free_dev;
- }
+ st->reg = devm_regulator_get(&spi->dev, "vcc");
+ if (IS_ERR(st->reg))
+ return PTR_ERR(st->reg);
ret = regulator_enable(st->reg);
if (ret)
- goto error_put_reg;
+ return ret;
spi_set_drvdata(spi, indio_dev);
@@ -268,12 +265,7 @@ error_ring_unregister:
iio_triggered_buffer_cleanup(indio_dev);
error_disable_reg:
regulator_disable(st->reg);
-error_put_reg:
- regulator_put(st->reg);
-error_free_dev:
- iio_device_free(indio_dev);
-error_ret:
return ret;
}
@@ -285,8 +277,6 @@ static int ad7476_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
regulator_disable(st->reg);
- regulator_put(st->reg);
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/iio/adc/ad7791.c b/drivers/iio/adc/ad7791.c
index 5e8d1da6887f..c20203577d2d 100644
--- a/drivers/iio/adc/ad7791.c
+++ b/drivers/iio/adc/ad7791.c
@@ -361,21 +361,19 @@ static int ad7791_probe(struct spi_device *spi)
return -ENXIO;
}
- indio_dev = iio_device_alloc(sizeof(*st));
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
st = iio_priv(indio_dev);
- st->reg = regulator_get(&spi->dev, "refin");
- if (IS_ERR(st->reg)) {
- ret = PTR_ERR(st->reg);
- goto err_iio_free;
- }
+ st->reg = devm_regulator_get(&spi->dev, "refin");
+ if (IS_ERR(st->reg))
+ return PTR_ERR(st->reg);
ret = regulator_enable(st->reg);
if (ret)
- goto error_put_reg;
+ return ret;
st->info = &ad7791_chip_infos[spi_get_device_id(spi)->driver_data];
ad_sd_init(&st->sd, indio_dev, spi, &ad7791_sigma_delta_info);
@@ -410,10 +408,6 @@ error_remove_trigger:
ad_sd_cleanup_buffer_and_trigger(indio_dev);
error_disable_reg:
regulator_disable(st->reg);
-error_put_reg:
- regulator_put(st->reg);
-err_iio_free:
- iio_device_free(indio_dev);
return ret;
}
@@ -427,9 +421,6 @@ static int ad7791_remove(struct spi_device *spi)
ad_sd_cleanup_buffer_and_trigger(indio_dev);
regulator_disable(st->reg);
- regulator_put(st->reg);
-
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/iio/adc/ad7793.c b/drivers/iio/adc/ad7793.c
index 334e31ff7a4e..4dddeabdfbb0 100644
--- a/drivers/iio/adc/ad7793.c
+++ b/drivers/iio/adc/ad7793.c
@@ -757,7 +757,7 @@ static int ad7793_probe(struct spi_device *spi)
return -ENODEV;
}
- indio_dev = iio_device_alloc(sizeof(*st));
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
@@ -766,15 +766,13 @@ static int ad7793_probe(struct spi_device *spi)
ad_sd_init(&st->sd, indio_dev, spi, &ad7793_sigma_delta_info);
if (pdata->refsel != AD7793_REFSEL_INTERNAL) {
- st->reg = regulator_get(&spi->dev, "refin");
- if (IS_ERR(st->reg)) {
- ret = PTR_ERR(st->reg);
- goto error_device_free;
- }
+ st->reg = devm_regulator_get(&spi->dev, "refin");
+ if (IS_ERR(st->reg))
+ return PTR_ERR(st->reg);
ret = regulator_enable(st->reg);
if (ret)
- goto error_put_reg;
+ return ret;
vref_mv = regulator_get_voltage(st->reg);
if (vref_mv < 0) {
@@ -818,11 +816,6 @@ error_remove_trigger:
error_disable_reg:
if (pdata->refsel != AD7793_REFSEL_INTERNAL)
regulator_disable(st->reg);
-error_put_reg:
- if (pdata->refsel != AD7793_REFSEL_INTERNAL)
- regulator_put(st->reg);
-error_device_free:
- iio_device_free(indio_dev);
return ret;
}
@@ -836,12 +829,8 @@ static int ad7793_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
ad_sd_cleanup_buffer_and_trigger(indio_dev);
- if (pdata->refsel != AD7793_REFSEL_INTERNAL) {
+ if (pdata->refsel != AD7793_REFSEL_INTERNAL)
regulator_disable(st->reg);
- regulator_put(st->reg);
- }
-
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/iio/adc/ad7887.c b/drivers/iio/adc/ad7887.c
index dd15a5b0f701..9dd077b78759 100644
--- a/drivers/iio/adc/ad7887.c
+++ b/drivers/iio/adc/ad7887.c
@@ -237,25 +237,24 @@ static int ad7887_probe(struct spi_device *spi)
{
struct ad7887_platform_data *pdata = spi->dev.platform_data;
struct ad7887_state *st;
- struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
+ struct iio_dev *indio_dev;
uint8_t mode;
int ret;
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
st = iio_priv(indio_dev);
if (!pdata || !pdata->use_onchip_ref) {
- st->reg = regulator_get(&spi->dev, "vref");
- if (IS_ERR(st->reg)) {
- ret = PTR_ERR(st->reg);
- goto error_free;
- }
+ st->reg = devm_regulator_get(&spi->dev, "vref");
+ if (IS_ERR(st->reg))
+ return PTR_ERR(st->reg);
ret = regulator_enable(st->reg);
if (ret)
- goto error_put_reg;
+ return ret;
}
st->chip_info =
@@ -331,11 +330,6 @@ error_unregister_ring:
error_disable_reg:
if (st->reg)
regulator_disable(st->reg);
-error_put_reg:
- if (st->reg)
- regulator_put(st->reg);
-error_free:
- iio_device_free(indio_dev);
return ret;
}
@@ -347,11 +341,8 @@ static int ad7887_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
- if (st->reg) {
+ if (st->reg)
regulator_disable(st->reg);
- regulator_put(st->reg);
- }
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/iio/adc/ad7923.c b/drivers/iio/adc/ad7923.c
index 97fa0d3dc4aa..4108dbb28c3d 100644
--- a/drivers/iio/adc/ad7923.c
+++ b/drivers/iio/adc/ad7923.c
@@ -275,10 +275,11 @@ static const struct iio_info ad7923_info = {
static int ad7923_probe(struct spi_device *spi)
{
struct ad7923_state *st;
- struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
+ struct iio_dev *indio_dev;
const struct ad7923_chip_info *info;
int ret;
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
@@ -311,14 +312,13 @@ static int ad7923_probe(struct spi_device *spi)
spi_message_add_tail(&st->scan_single_xfer[0], &st->scan_single_msg);
spi_message_add_tail(&st->scan_single_xfer[1], &st->scan_single_msg);
- st->reg = regulator_get(&spi->dev, "refin");
- if (IS_ERR(st->reg)) {
- ret = PTR_ERR(st->reg);
- goto error_free;
- }
+ st->reg = devm_regulator_get(&spi->dev, "refin");
+ if (IS_ERR(st->reg))
+ return PTR_ERR(st->reg);
+
ret = regulator_enable(st->reg);
if (ret)
- goto error_put_reg;
+ return ret;
ret = iio_triggered_buffer_setup(indio_dev, NULL,
&ad7923_trigger_handler, NULL);
@@ -335,10 +335,6 @@ error_cleanup_ring:
iio_triggered_buffer_cleanup(indio_dev);
error_disable_reg:
regulator_disable(st->reg);
-error_put_reg:
- regulator_put(st->reg);
-error_free:
- iio_device_free(indio_dev);
return ret;
}
@@ -351,8 +347,6 @@ static int ad7923_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
regulator_disable(st->reg);
- regulator_put(st->reg);
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c
index b6db6a0e09cd..423e079460d3 100644
--- a/drivers/iio/adc/at91_adc.c
+++ b/drivers/iio/adc/at91_adc.c
@@ -589,11 +589,9 @@ static int at91_adc_probe(struct platform_device *pdev)
struct resource *res;
u32 reg;
- idev = iio_device_alloc(sizeof(struct at91_adc_state));
- if (idev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ idev = devm_iio_device_alloc(&pdev->dev, sizeof(struct at91_adc_state));
+ if (!idev)
+ return -ENOMEM;
st = iio_priv(idev);
@@ -604,8 +602,7 @@ static int at91_adc_probe(struct platform_device *pdev)
if (ret) {
dev_err(&pdev->dev, "No platform data available.\n");
- ret = -EINVAL;
- goto error_free_device;
+ return -EINVAL;
}
platform_set_drvdata(pdev, idev);
@@ -618,16 +615,14 @@ static int at91_adc_probe(struct platform_device *pdev)
st->irq = platform_get_irq(pdev, 0);
if (st->irq < 0) {
dev_err(&pdev->dev, "No IRQ ID is designated\n");
- ret = -ENODEV;
- goto error_free_device;
+ return -ENODEV;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
st->reg_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(st->reg_base)) {
- ret = PTR_ERR(st->reg_base);
- goto error_free_device;
+ return PTR_ERR(st->reg_base);
}
/*
@@ -642,7 +637,7 @@ static int at91_adc_probe(struct platform_device *pdev)
idev);
if (ret) {
dev_err(&pdev->dev, "Failed to allocate IRQ.\n");
- goto error_free_device;
+ return ret;
}
st->clk = devm_clk_get(&pdev->dev, "adc_clk");
@@ -752,9 +747,6 @@ error_disable_clk:
clk_disable_unprepare(st->clk);
error_free_irq:
free_irq(st->irq, idev);
-error_free_device:
- iio_device_free(idev);
-error_ret:
return ret;
}
@@ -769,7 +761,6 @@ static int at91_adc_remove(struct platform_device *pdev)
clk_disable_unprepare(st->adc_clk);
clk_disable_unprepare(st->clk);
free_irq(st->irq, idev);
- iio_device_free(idev);
return 0;
}
diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c
index 9809fc9a35d2..d25b262193a7 100644
--- a/drivers/iio/adc/exynos_adc.c
+++ b/drivers/iio/adc/exynos_adc.c
@@ -33,6 +33,7 @@
#include <linux/of_irq.h>
#include <linux/regulator/consumer.h>
#include <linux/of_platform.h>
+#include <linux/err.h>
#include <linux/iio/iio.h>
#include <linux/iio/machine.h>
@@ -261,7 +262,7 @@ static int exynos_adc_probe(struct platform_device *pdev)
if (!np)
return ret;
- indio_dev = iio_device_alloc(sizeof(struct exynos_adc));
+ indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct exynos_adc));
if (!indio_dev) {
dev_err(&pdev->dev, "failed allocating iio device\n");
return -ENOMEM;
@@ -271,23 +272,18 @@ static int exynos_adc_probe(struct platform_device *pdev)
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
info->regs = devm_ioremap_resource(&pdev->dev, mem);
- if (IS_ERR(info->regs)) {
- ret = PTR_ERR(info->regs);
- goto err_iio;
- }
+ if (IS_ERR(info->regs))
+ return PTR_ERR(info->regs);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
info->enable_reg = devm_ioremap_resource(&pdev->dev, mem);
- if (IS_ERR(info->enable_reg)) {
- ret = PTR_ERR(info->enable_reg);
- goto err_iio;
- }
+ if (IS_ERR(info->enable_reg))
+ return PTR_ERR(info->enable_reg);
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "no irq resource?\n");
- ret = irq;
- goto err_iio;
+ return irq;
}
info->irq = irq;
@@ -299,7 +295,7 @@ static int exynos_adc_probe(struct platform_device *pdev)
if (ret < 0) {
dev_err(&pdev->dev, "failed requesting irq, irq = %d\n",
info->irq);
- goto err_iio;
+ return ret;
}
writel(1, info->enable_reg);
@@ -365,8 +361,6 @@ err_iio_dev:
iio_device_unregister(indio_dev);
err_irq:
free_irq(info->irq, info);
-err_iio:
- iio_device_free(indio_dev);
return ret;
}
@@ -382,7 +376,6 @@ static int exynos_adc_remove(struct platform_device *pdev)
writel(0, info->enable_reg);
iio_device_unregister(indio_dev);
free_irq(info->irq, info);
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/iio/adc/lp8788_adc.c b/drivers/iio/adc/lp8788_adc.c
index 62bc39e9c94f..5c8c91595f47 100644
--- a/drivers/iio/adc/lp8788_adc.c
+++ b/drivers/iio/adc/lp8788_adc.c
@@ -194,7 +194,7 @@ static int lp8788_adc_probe(struct platform_device *pdev)
struct lp8788_adc *adc;
int ret;
- indio_dev = iio_device_alloc(sizeof(*adc));
+ indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc));
if (!indio_dev)
return -ENOMEM;
@@ -205,7 +205,7 @@ static int lp8788_adc_probe(struct platform_device *pdev)
indio_dev->dev.of_node = pdev->dev.of_node;
ret = lp8788_iio_map_register(indio_dev, lp->pdata, adc);
if (ret)
- goto err_iio_map;
+ return ret;
mutex_init(&adc->lock);
@@ -226,8 +226,6 @@ static int lp8788_adc_probe(struct platform_device *pdev)
err_iio_device:
iio_map_array_unregister(indio_dev);
-err_iio_map:
- iio_device_free(indio_dev);
return ret;
}
@@ -237,7 +235,6 @@ static int lp8788_adc_remove(struct platform_device *pdev)
iio_device_unregister(indio_dev);
iio_map_array_unregister(indio_dev);
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/iio/adc/max1363.c b/drivers/iio/adc/max1363.c
index f148d00b83f7..4fb35d1d7494 100644
--- a/drivers/iio/adc/max1363.c
+++ b/drivers/iio/adc/max1363.c
@@ -1498,16 +1498,15 @@ static int max1363_probe(struct i2c_client *client,
struct iio_dev *indio_dev;
struct regulator *vref;
- indio_dev = iio_device_alloc(sizeof(struct max1363_state));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_out;
- }
+ indio_dev = devm_iio_device_alloc(&client->dev,
+ sizeof(struct max1363_state));
+ if (!indio_dev)
+ return -ENOMEM;
indio_dev->dev.of_node = client->dev.of_node;
ret = iio_map_array_register(indio_dev, client->dev.platform_data);
if (ret < 0)
- goto error_free_device;
+ return ret;
st = iio_priv(indio_dev);
@@ -1590,9 +1589,6 @@ error_disable_reg:
regulator_disable(st->reg);
error_unregister_map:
iio_map_array_unregister(indio_dev);
-error_free_device:
- iio_device_free(indio_dev);
-error_out:
return ret;
}
@@ -1607,7 +1603,6 @@ static int max1363_remove(struct i2c_client *client)
regulator_disable(st->vref);
regulator_disable(st->reg);
iio_map_array_unregister(indio_dev);
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/iio/adc/mcp320x.c b/drivers/iio/adc/mcp320x.c
index ebc015922a79..28a086e48776 100644
--- a/drivers/iio/adc/mcp320x.c
+++ b/drivers/iio/adc/mcp320x.c
@@ -169,7 +169,7 @@ static int mcp320x_probe(struct spi_device *spi)
const struct mcp3208_chip_info *chip_info;
int ret;
- indio_dev = iio_device_alloc(sizeof(*adc));
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc));
if (!indio_dev)
return -ENOMEM;
@@ -193,15 +193,13 @@ static int mcp320x_probe(struct spi_device *spi)
spi_message_init_with_transfers(&adc->msg, adc->transfer,
ARRAY_SIZE(adc->transfer));
- adc->reg = regulator_get(&spi->dev, "vref");
- if (IS_ERR(adc->reg)) {
- ret = PTR_ERR(adc->reg);
- goto iio_free;
- }
+ adc->reg = devm_regulator_get(&spi->dev, "vref");
+ if (IS_ERR(adc->reg))
+ return PTR_ERR(adc->reg);
ret = regulator_enable(adc->reg);
if (ret < 0)
- goto reg_free;
+ return ret;
mutex_init(&adc->lock);
@@ -213,10 +211,6 @@ static int mcp320x_probe(struct spi_device *spi)
reg_disable:
regulator_disable(adc->reg);
-reg_free:
- regulator_put(adc->reg);
-iio_free:
- iio_device_free(indio_dev);
return ret;
}
@@ -228,8 +222,6 @@ static int mcp320x_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
regulator_disable(adc->reg);
- regulator_put(adc->reg);
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/iio/adc/nau7802.c b/drivers/iio/adc/nau7802.c
new file mode 100644
index 000000000000..bdf03468f3b8
--- /dev/null
+++ b/drivers/iio/adc/nau7802.c
@@ -0,0 +1,581 @@
+/*
+ * Driver for the Nuvoton NAU7802 ADC
+ *
+ * Copyright 2013 Free Electrons
+ *
+ * Licensed under the GPLv2 or later.
+ */
+
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/wait.h>
+#include <linux/log2.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+#define NAU7802_REG_PUCTRL 0x00
+#define NAU7802_PUCTRL_RR(x) (x << 0)
+#define NAU7802_PUCTRL_RR_BIT NAU7802_PUCTRL_RR(1)
+#define NAU7802_PUCTRL_PUD(x) (x << 1)
+#define NAU7802_PUCTRL_PUD_BIT NAU7802_PUCTRL_PUD(1)
+#define NAU7802_PUCTRL_PUA(x) (x << 2)
+#define NAU7802_PUCTRL_PUA_BIT NAU7802_PUCTRL_PUA(1)
+#define NAU7802_PUCTRL_PUR(x) (x << 3)
+#define NAU7802_PUCTRL_PUR_BIT NAU7802_PUCTRL_PUR(1)
+#define NAU7802_PUCTRL_CS(x) (x << 4)
+#define NAU7802_PUCTRL_CS_BIT NAU7802_PUCTRL_CS(1)
+#define NAU7802_PUCTRL_CR(x) (x << 5)
+#define NAU7802_PUCTRL_CR_BIT NAU7802_PUCTRL_CR(1)
+#define NAU7802_PUCTRL_AVDDS(x) (x << 7)
+#define NAU7802_PUCTRL_AVDDS_BIT NAU7802_PUCTRL_AVDDS(1)
+#define NAU7802_REG_CTRL1 0x01
+#define NAU7802_CTRL1_VLDO(x) (x << 3)
+#define NAU7802_CTRL1_GAINS(x) (x)
+#define NAU7802_CTRL1_GAINS_BITS 0x07
+#define NAU7802_REG_CTRL2 0x02
+#define NAU7802_CTRL2_CHS(x) (x << 7)
+#define NAU7802_CTRL2_CRS(x) (x << 4)
+#define NAU7802_SAMP_FREQ_320 0x07
+#define NAU7802_CTRL2_CHS_BIT NAU7802_CTRL2_CHS(1)
+#define NAU7802_REG_ADC_B2 0x12
+#define NAU7802_REG_ADC_B1 0x13
+#define NAU7802_REG_ADC_B0 0x14
+#define NAU7802_REG_ADC_CTRL 0x15
+
+#define NAU7802_MIN_CONVERSIONS 6
+
+struct nau7802_state {
+ struct i2c_client *client;
+ s32 last_value;
+ struct mutex lock;
+ struct mutex data_lock;
+ u32 vref_mv;
+ u32 conversion_count;
+ u32 min_conversions;
+ u8 sample_rate;
+ u32 scale_avail[8];
+ struct completion value_ok;
+};
+
+#define NAU7802_CHANNEL(chan) { \
+ .type = IIO_VOLTAGE, \
+ .indexed = 1, \
+ .channel = (chan), \
+ .scan_index = (chan), \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
+ BIT(IIO_CHAN_INFO_SAMP_FREQ) \
+}
+
+static const struct iio_chan_spec nau7802_chan_array[] = {
+ NAU7802_CHANNEL(0),
+ NAU7802_CHANNEL(1),
+};
+
+static const u16 nau7802_sample_freq_avail[] = {10, 20, 40, 80,
+ 10, 10, 10, 320};
+
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("10 40 80 320");
+
+static struct attribute *nau7802_attributes[] = {
+ &iio_const_attr_sampling_frequency_available.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group nau7802_attribute_group = {
+ .attrs = nau7802_attributes,
+};
+
+static int nau7802_set_gain(struct nau7802_state *st, int gain)
+{
+ int ret;
+
+ mutex_lock(&st->lock);
+ st->conversion_count = 0;
+
+ ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_CTRL1);
+ if (ret < 0)
+ goto nau7802_sysfs_set_gain_out;
+ ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_CTRL1,
+ (ret & (~NAU7802_CTRL1_GAINS_BITS)) |
+ gain);
+
+nau7802_sysfs_set_gain_out:
+ mutex_unlock(&st->lock);
+
+ return ret;
+}
+
+static int nau7802_read_conversion(struct nau7802_state *st)
+{
+ int data;
+
+ mutex_lock(&st->data_lock);
+ data = i2c_smbus_read_byte_data(st->client, NAU7802_REG_ADC_B2);
+ if (data < 0)
+ goto nau7802_read_conversion_out;
+ st->last_value = data << 16;
+
+ data = i2c_smbus_read_byte_data(st->client, NAU7802_REG_ADC_B1);
+ if (data < 0)
+ goto nau7802_read_conversion_out;
+ st->last_value |= data << 8;
+
+ data = i2c_smbus_read_byte_data(st->client, NAU7802_REG_ADC_B0);
+ if (data < 0)
+ goto nau7802_read_conversion_out;
+ st->last_value |= data;
+
+ st->last_value = sign_extend32(st->last_value, 23);
+
+nau7802_read_conversion_out:
+ mutex_unlock(&st->data_lock);
+
+ return data;
+}
+
+/*
+ * Conversions are synchronised on the rising edge of NAU7802_PUCTRL_CS_BIT
+ */
+static int nau7802_sync(struct nau7802_state *st)
+{
+ int ret;
+
+ ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_PUCTRL);
+ if (ret < 0)
+ return ret;
+ ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_PUCTRL,
+ ret | NAU7802_PUCTRL_CS_BIT);
+
+ return ret;
+}
+
+static irqreturn_t nau7802_eoc_trigger(int irq, void *private)
+{
+ struct iio_dev *indio_dev = private;
+ struct nau7802_state *st = iio_priv(indio_dev);
+ int status;
+
+ status = i2c_smbus_read_byte_data(st->client, NAU7802_REG_PUCTRL);
+ if (status < 0)
+ return IRQ_HANDLED;
+
+ if (!(status & NAU7802_PUCTRL_CR_BIT))
+ return IRQ_NONE;
+
+ if (nau7802_read_conversion(st) < 0)
+ return IRQ_HANDLED;
+
+ /*
+ * Because there is actually only one ADC for both channels, we have to
+ * wait for enough conversions to happen before getting a significant
+ * value when changing channels and the values are far apart.
+ */
+ if (st->conversion_count < NAU7802_MIN_CONVERSIONS)
+ st->conversion_count++;
+ if (st->conversion_count >= NAU7802_MIN_CONVERSIONS)
+ complete_all(&st->value_ok);
+
+ return IRQ_HANDLED;
+}
+
+static int nau7802_read_irq(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val)
+{
+ struct nau7802_state *st = iio_priv(indio_dev);
+ int ret;
+
+ INIT_COMPLETION(st->value_ok);
+ enable_irq(st->client->irq);
+
+ nau7802_sync(st);
+
+ /* read registers to ensure we flush everything */
+ ret = nau7802_read_conversion(st);
+ if (ret < 0)
+ goto read_chan_info_failure;
+
+ /* Wait for a conversion to finish */
+ ret = wait_for_completion_interruptible_timeout(&st->value_ok,
+ msecs_to_jiffies(1000));
+ if (ret == 0)
+ ret = -ETIMEDOUT;
+
+ if (ret < 0)
+ goto read_chan_info_failure;
+
+ disable_irq(st->client->irq);
+
+ *val = st->last_value;
+
+ return IIO_VAL_INT;
+
+read_chan_info_failure:
+ disable_irq(st->client->irq);
+
+ return ret;
+}
+
+static int nau7802_read_poll(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val)
+{
+ struct nau7802_state *st = iio_priv(indio_dev);
+ int ret;
+
+ nau7802_sync(st);
+
+ /* read registers to ensure we flush everything */
+ ret = nau7802_read_conversion(st);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * Because there is actually only one ADC for both channels, we have to
+ * wait for enough conversions to happen before getting a significant
+ * value when changing channels and the values are far appart.
+ */
+ do {
+ ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_PUCTRL);
+ if (ret < 0)
+ return ret;
+
+ while (!(ret & NAU7802_PUCTRL_CR_BIT)) {
+ if (st->sample_rate != NAU7802_SAMP_FREQ_320)
+ msleep(20);
+ else
+ mdelay(4);
+ ret = i2c_smbus_read_byte_data(st->client,
+ NAU7802_REG_PUCTRL);
+ if (ret < 0)
+ return ret;
+ }
+
+ ret = nau7802_read_conversion(st);
+ if (ret < 0)
+ return ret;
+ if (st->conversion_count < NAU7802_MIN_CONVERSIONS)
+ st->conversion_count++;
+ } while (st->conversion_count < NAU7802_MIN_CONVERSIONS);
+
+ *val = st->last_value;
+
+ return IIO_VAL_INT;
+}
+
+static int nau7802_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct nau7802_state *st = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ mutex_lock(&st->lock);
+ /*
+ * Select the channel to use
+ * - Channel 1 is value 0 in the CHS register
+ * - Channel 2 is value 1 in the CHS register
+ */
+ ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_CTRL2);
+ if (ret < 0) {
+ mutex_unlock(&st->lock);
+ return ret;
+ }
+
+ if (((ret & NAU7802_CTRL2_CHS_BIT) && !chan->channel) ||
+ (!(ret & NAU7802_CTRL2_CHS_BIT) &&
+ chan->channel)) {
+ st->conversion_count = 0;
+ ret = i2c_smbus_write_byte_data(st->client,
+ NAU7802_REG_CTRL2,
+ NAU7802_CTRL2_CHS(chan->channel) |
+ NAU7802_CTRL2_CRS(st->sample_rate));
+
+ if (ret < 0) {
+ mutex_unlock(&st->lock);
+ return ret;
+ }
+ }
+
+ if (st->client->irq)
+ ret = nau7802_read_irq(indio_dev, chan, val);
+ else
+ ret = nau7802_read_poll(indio_dev, chan, val);
+
+ mutex_unlock(&st->lock);
+ return ret;
+
+ case IIO_CHAN_INFO_SCALE:
+ ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_CTRL1);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * We have 24 bits of signed data, that means 23 bits of data
+ * plus the sign bit
+ */
+ *val = st->vref_mv;
+ *val2 = 23 + (ret & NAU7802_CTRL1_GAINS_BITS);
+
+ return IIO_VAL_FRACTIONAL_LOG2;
+
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ *val = nau7802_sample_freq_avail[st->sample_rate];
+ *val2 = 0;
+ return IIO_VAL_INT;
+
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static int nau7802_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val, int val2, long mask)
+{
+ struct nau7802_state *st = iio_priv(indio_dev);
+ int i, ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SCALE:
+ for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++)
+ if (val2 == st->scale_avail[i])
+ return nau7802_set_gain(st, i);
+
+ break;
+
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ for (i = 0; i < ARRAY_SIZE(nau7802_sample_freq_avail); i++)
+ if (val == nau7802_sample_freq_avail[i]) {
+ mutex_lock(&st->lock);
+ st->sample_rate = i;
+ st->conversion_count = 0;
+ ret = i2c_smbus_write_byte_data(st->client,
+ NAU7802_REG_CTRL2,
+ NAU7802_CTRL2_CRS(st->sample_rate));
+ mutex_unlock(&st->lock);
+ return ret;
+ }
+
+ break;
+
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static int nau7802_write_raw_get_fmt(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ long mask)
+{
+ return IIO_VAL_INT_PLUS_NANO;
+}
+
+static const struct iio_info nau7802_info = {
+ .driver_module = THIS_MODULE,
+ .read_raw = &nau7802_read_raw,
+ .write_raw = &nau7802_write_raw,
+ .write_raw_get_fmt = nau7802_write_raw_get_fmt,
+ .attrs = &nau7802_attribute_group,
+};
+
+static int nau7802_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct iio_dev *indio_dev;
+ struct nau7802_state *st;
+ struct device_node *np = client->dev.of_node;
+ int i, ret;
+ u8 data;
+ u32 tmp = 0;
+
+ if (!client->dev.of_node) {
+ dev_err(&client->dev, "No device tree node available.\n");
+ return -EINVAL;
+ }
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
+ if (indio_dev == NULL)
+ return -ENOMEM;
+
+ st = iio_priv(indio_dev);
+
+ i2c_set_clientdata(client, indio_dev);
+
+ indio_dev->dev.parent = &client->dev;
+ indio_dev->name = dev_name(&client->dev);
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->info = &nau7802_info;
+
+ st->client = client;
+
+ /* Reset the device */
+ ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_PUCTRL,
+ NAU7802_PUCTRL_RR_BIT);
+ if (ret < 0)
+ return ret;
+
+ /* Enter normal operation mode */
+ ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_PUCTRL,
+ NAU7802_PUCTRL_PUD_BIT);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * After about 200 usecs, the device should be ready and then
+ * the Power Up bit will be set to 1. If not, wait for it.
+ */
+ udelay(210);
+ ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_PUCTRL);
+ if (ret < 0)
+ return ret;
+ if (!(ret & NAU7802_PUCTRL_PUR_BIT))
+ return ret;
+
+ of_property_read_u32(np, "nuvoton,vldo", &tmp);
+ st->vref_mv = tmp;
+
+ data = NAU7802_PUCTRL_PUD_BIT | NAU7802_PUCTRL_PUA_BIT |
+ NAU7802_PUCTRL_CS_BIT;
+ if (tmp >= 2400)
+ data |= NAU7802_PUCTRL_AVDDS_BIT;
+
+ ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_PUCTRL, data);
+ if (ret < 0)
+ return ret;
+ ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_ADC_CTRL, 0x30);
+ if (ret < 0)
+ return ret;
+
+ if (tmp >= 2400) {
+ data = NAU7802_CTRL1_VLDO((4500 - tmp) / 300);
+ ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_CTRL1,
+ data);
+ if (ret < 0)
+ return ret;
+ }
+
+ /* Populate available ADC input ranges */
+ for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++)
+ st->scale_avail[i] = (((u64)st->vref_mv) * 1000000000ULL)
+ >> (23 + i);
+
+ init_completion(&st->value_ok);
+
+ /*
+ * The ADC fires continuously and we can't do anything about
+ * it. So we need to have the IRQ disabled by default, and we
+ * will enable them back when we will need them..
+ */
+ if (client->irq) {
+ ret = request_threaded_irq(client->irq,
+ NULL,
+ nau7802_eoc_trigger,
+ IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+ client->dev.driver->name,
+ indio_dev);
+ if (ret) {
+ /*
+ * What may happen here is that our IRQ controller is
+ * not able to get level interrupt but this is required
+ * by this ADC as when going over 40 sample per second,
+ * the interrupt line may stay high between conversions.
+ * So, we continue no matter what but we switch to
+ * polling mode.
+ */
+ dev_info(&client->dev,
+ "Failed to allocate IRQ, using polling mode\n");
+ client->irq = 0;
+ } else
+ disable_irq(client->irq);
+ }
+
+ if (!client->irq) {
+ /*
+ * We are polling, use the fastest sample rate by
+ * default
+ */
+ st->sample_rate = NAU7802_SAMP_FREQ_320;
+ ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_CTRL2,
+ NAU7802_CTRL2_CRS(st->sample_rate));
+ if (ret)
+ goto error_free_irq;
+ }
+
+ /* Setup the ADC channels available on the board */
+ indio_dev->num_channels = ARRAY_SIZE(nau7802_chan_array);
+ indio_dev->channels = nau7802_chan_array;
+
+ mutex_init(&st->lock);
+ mutex_init(&st->data_lock);
+
+ ret = iio_device_register(indio_dev);
+ if (ret < 0) {
+ dev_err(&client->dev, "Couldn't register the device.\n");
+ goto error_device_register;
+ }
+
+ return 0;
+
+error_device_register:
+ mutex_destroy(&st->lock);
+ mutex_destroy(&st->data_lock);
+error_free_irq:
+ if (client->irq)
+ free_irq(client->irq, indio_dev);
+
+ return ret;
+}
+
+static int nau7802_remove(struct i2c_client *client)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct nau7802_state *st = iio_priv(indio_dev);
+
+ iio_device_unregister(indio_dev);
+ mutex_destroy(&st->lock);
+ mutex_destroy(&st->data_lock);
+ if (client->irq)
+ free_irq(client->irq, indio_dev);
+
+ return 0;
+}
+
+static const struct i2c_device_id nau7802_i2c_id[] = {
+ { "nau7802", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, nau7802_i2c_id);
+
+static const struct of_device_id nau7802_dt_ids[] = {
+ { .compatible = "nuvoton,nau7802" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, nau7802_dt_ids);
+
+static struct i2c_driver nau7802_driver = {
+ .probe = nau7802_probe,
+ .remove = nau7802_remove,
+ .id_table = nau7802_i2c_id,
+ .driver = {
+ .name = "nau7802",
+ .of_match_table = of_match_ptr(nau7802_dt_ids),
+ },
+};
+
+module_i2c_driver(nau7802_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Nuvoton NAU7802 ADC Driver");
+MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
+MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@free-electrons.com>");
diff --git a/drivers/iio/adc/ti-adc081c.c b/drivers/iio/adc/ti-adc081c.c
index 2826faae706c..ee5f72bffe5a 100644
--- a/drivers/iio/adc/ti-adc081c.c
+++ b/drivers/iio/adc/ti-adc081c.c
@@ -74,22 +74,20 @@ static int adc081c_probe(struct i2c_client *client,
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA))
return -ENODEV;
- iio = iio_device_alloc(sizeof(*adc));
+ iio = devm_iio_device_alloc(&client->dev, sizeof(*adc));
if (!iio)
return -ENOMEM;
adc = iio_priv(iio);
adc->i2c = client;
- adc->ref = regulator_get(&client->dev, "vref");
- if (IS_ERR(adc->ref)) {
- err = PTR_ERR(adc->ref);
- goto iio_free;
- }
+ adc->ref = devm_regulator_get(&client->dev, "vref");
+ if (IS_ERR(adc->ref))
+ return PTR_ERR(adc->ref);
err = regulator_enable(adc->ref);
if (err < 0)
- goto regulator_put;
+ return err;
iio->dev.parent = &client->dev;
iio->name = dev_name(&client->dev);
@@ -109,10 +107,6 @@ static int adc081c_probe(struct i2c_client *client,
regulator_disable:
regulator_disable(adc->ref);
-regulator_put:
- regulator_put(adc->ref);
-iio_free:
- iio_device_free(iio);
return err;
}
@@ -124,8 +118,6 @@ static int adc081c_remove(struct i2c_client *client)
iio_device_unregister(iio);
regulator_disable(adc->ref);
- regulator_put(adc->ref);
- iio_device_free(iio);
return 0;
}
diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
index 0ad208a69c29..b53867cb9cdc 100644
--- a/drivers/iio/adc/ti_am335x_adc.c
+++ b/drivers/iio/adc/ti_am335x_adc.c
@@ -202,11 +202,11 @@ static int tiadc_probe(struct platform_device *pdev)
return -EINVAL;
}
- indio_dev = iio_device_alloc(sizeof(struct tiadc_device));
+ indio_dev = devm_iio_device_alloc(&pdev->dev,
+ sizeof(struct tiadc_device));
if (indio_dev == NULL) {
dev_err(&pdev->dev, "failed to allocate iio device\n");
- err = -ENOMEM;
- goto err_ret;
+ return -ENOMEM;
}
adc_dev = iio_priv(indio_dev);
@@ -227,7 +227,7 @@ static int tiadc_probe(struct platform_device *pdev)
err = tiadc_channel_init(indio_dev, adc_dev->channels);
if (err < 0)
- goto err_free_device;
+ return err;
err = iio_device_register(indio_dev);
if (err)
@@ -239,9 +239,6 @@ static int tiadc_probe(struct platform_device *pdev)
err_free_channels:
tiadc_channels_remove(indio_dev);
-err_free_device:
- iio_device_free(indio_dev);
-err_ret:
return err;
}
@@ -257,8 +254,6 @@ static int tiadc_remove(struct platform_device *pdev)
step_en = get_adc_step_mask(adc_dev);
am335x_tsc_se_clr(adc_dev->mfd_tscadc, step_en);
- iio_device_free(indio_dev);
-
return 0;
}
diff --git a/drivers/iio/adc/viperboard_adc.c b/drivers/iio/adc/viperboard_adc.c
index 56ac481c73c0..09727a71e9fa 100644
--- a/drivers/iio/adc/viperboard_adc.c
+++ b/drivers/iio/adc/viperboard_adc.c
@@ -124,7 +124,7 @@ static int vprbrd_adc_probe(struct platform_device *pdev)
int ret;
/* registering iio */
- indio_dev = iio_device_alloc(sizeof(*adc));
+ indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc));
if (!indio_dev) {
dev_err(&pdev->dev, "failed allocating iio device\n");
return -ENOMEM;
@@ -142,16 +142,12 @@ static int vprbrd_adc_probe(struct platform_device *pdev)
ret = iio_device_register(indio_dev);
if (ret) {
dev_err(&pdev->dev, "could not register iio (adc)");
- goto error;
+ return ret;
}
platform_set_drvdata(pdev, indio_dev);
return 0;
-
-error:
- iio_device_free(indio_dev);
- return ret;
}
static int vprbrd_adc_remove(struct platform_device *pdev)
@@ -159,7 +155,6 @@ static int vprbrd_adc_remove(struct platform_device *pdev)
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
iio_device_unregister(indio_dev);
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/iio/amplifiers/Kconfig b/drivers/iio/amplifiers/Kconfig
index 05d707ed7d4f..e9c5f2cd9257 100644
--- a/drivers/iio/amplifiers/Kconfig
+++ b/drivers/iio/amplifiers/Kconfig
@@ -1,6 +1,8 @@
#
# Gain Amplifiers, etc.
#
+# When adding new entries keep the list in alphabetical order
+
menu "Amplifiers"
config AD8366
diff --git a/drivers/iio/amplifiers/Makefile b/drivers/iio/amplifiers/Makefile
index a6ca366908e0..8da4b787898a 100644
--- a/drivers/iio/amplifiers/Makefile
+++ b/drivers/iio/amplifiers/Makefile
@@ -2,4 +2,5 @@
# Makefile iio/amplifiers
#
+# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_AD8366) += ad8366.o
diff --git a/drivers/iio/amplifiers/ad8366.c b/drivers/iio/amplifiers/ad8366.c
index d354554b51b3..d0a79a4bce1c 100644
--- a/drivers/iio/amplifiers/ad8366.c
+++ b/drivers/iio/amplifiers/ad8366.c
@@ -139,17 +139,17 @@ static int ad8366_probe(struct spi_device *spi)
struct ad8366_state *st;
int ret;
- indio_dev = iio_device_alloc(sizeof(*st));
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
st = iio_priv(indio_dev);
- st->reg = regulator_get(&spi->dev, "vcc");
+ st->reg = devm_regulator_get(&spi->dev, "vcc");
if (!IS_ERR(st->reg)) {
ret = regulator_enable(st->reg);
if (ret)
- goto error_put_reg;
+ return ret;
}
spi_set_drvdata(spi, indio_dev);
@@ -173,11 +173,6 @@ static int ad8366_probe(struct spi_device *spi)
error_disable_reg:
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
-error_put_reg:
- if (!IS_ERR(st->reg))
- regulator_put(st->reg);
-
- iio_device_free(indio_dev);
return ret;
}
@@ -195,8 +190,6 @@ static int ad8366_remove(struct spi_device *spi)
regulator_put(reg);
}
- iio_device_free(indio_dev);
-
return 0;
}
diff --git a/drivers/iio/common/Makefile b/drivers/iio/common/Makefile
index c2352beb5d97..3112df0060e9 100644
--- a/drivers/iio/common/Makefile
+++ b/drivers/iio/common/Makefile
@@ -6,5 +6,6 @@
# instead of duplicating in each module.
#
+# When adding new entries keep the list in alphabetical order
obj-y += hid-sensors/
obj-y += st_sensors/
diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c
index 865b1781df66..965ee22d3ac8 100644
--- a/drivers/iio/common/st_sensors/st_sensors_core.c
+++ b/drivers/iio/common/st_sensors/st_sensors_core.c
@@ -22,7 +22,7 @@
static inline u32 st_sensors_get_unaligned_le24(const u8 *p)
{
- return ((s32)((p[0] | p[1] << 8 | p[2] << 16) << 8) >> 8);
+ return (s32)((p[0] | p[1] << 8 | p[2] << 16) << 8) >> 8;
}
static int st_sensors_write_data_with_mask(struct iio_dev *indio_dev,
@@ -118,7 +118,7 @@ st_sensors_match_odr_error:
}
static int st_sensors_set_fullscale(struct iio_dev *indio_dev,
- unsigned int fs)
+ unsigned int fs)
{
int err, i = 0;
struct st_sensor_data *sdata = iio_priv(indio_dev);
@@ -198,13 +198,39 @@ int st_sensors_set_axis_enable(struct iio_dev *indio_dev, u8 axis_enable)
}
EXPORT_SYMBOL(st_sensors_set_axis_enable);
-int st_sensors_init_sensor(struct iio_dev *indio_dev)
+int st_sensors_init_sensor(struct iio_dev *indio_dev,
+ struct st_sensors_platform_data *pdata)
{
int err;
struct st_sensor_data *sdata = iio_priv(indio_dev);
mutex_init(&sdata->tb.buf_lock);
+ switch (pdata->drdy_int_pin) {
+ case 1:
+ if (sdata->sensor->drdy_irq.mask_int1 == 0) {
+ dev_err(&indio_dev->dev,
+ "DRDY on INT1 not available.\n");
+ err = -EINVAL;
+ goto init_error;
+ }
+ sdata->drdy_int_pin = 1;
+ break;
+ case 2:
+ if (sdata->sensor->drdy_irq.mask_int2 == 0) {
+ dev_err(&indio_dev->dev,
+ "DRDY on INT2 not available.\n");
+ err = -EINVAL;
+ goto init_error;
+ }
+ sdata->drdy_int_pin = 2;
+ break;
+ default:
+ dev_err(&indio_dev->dev, "DRDY on pdata not valid.\n");
+ err = -EINVAL;
+ goto init_error;
+ }
+
err = st_sensors_set_enable(indio_dev, false);
if (err < 0)
goto init_error;
@@ -234,6 +260,7 @@ EXPORT_SYMBOL(st_sensors_init_sensor);
int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable)
{
int err;
+ u8 drdy_mask;
struct st_sensor_data *sdata = iio_priv(indio_dev);
/* Enable/Disable the interrupt generator 1. */
@@ -245,10 +272,14 @@ int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable)
goto st_accel_set_dataready_irq_error;
}
+ if (sdata->drdy_int_pin == 1)
+ drdy_mask = sdata->sensor->drdy_irq.mask_int1;
+ else
+ drdy_mask = sdata->sensor->drdy_irq.mask_int2;
+
/* Enable/Disable the interrupt generator for data ready. */
err = st_sensors_write_data_with_mask(indio_dev,
- sdata->sensor->drdy_irq.addr,
- sdata->sensor->drdy_irq.mask, (int)enable);
+ sdata->sensor->drdy_irq.addr, drdy_mask, (int)enable);
st_accel_set_dataready_irq_error:
return err;
diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig
index c9c33ce32d3a..3c6a78a75b78 100644
--- a/drivers/iio/dac/Kconfig
+++ b/drivers/iio/dac/Kconfig
@@ -1,6 +1,8 @@
#
# DAC drivers
#
+# When adding new entries keep the list in alphabetical order
+
menu "Digital to analog converters"
config AD5064
@@ -15,7 +17,7 @@ config AD5064
module will be called ad5064.
config AD5360
- tristate "Analog Devices Analog Devices AD5360/61/62/63/70/71/73 DAC driver"
+ tristate "Analog Devices AD5360/61/62/63/70/71/73 DAC driver"
depends on SPI
help
Say yes here to build support for Analog Devices AD5360, AD5361,
@@ -48,13 +50,6 @@ config AD5421
To compile this driver as module choose M here: the module will be called
ad5421.
-config AD5624R_SPI
- tristate "Analog Devices AD5624/44/64R DAC spi driver"
- depends on SPI
- help
- Say yes here to build support for Analog Devices AD5624R, AD5644R and
- AD5664R converters (DAC). This driver uses the common SPI interface.
-
config AD5446
tristate "Analog Devices AD5446 and similar single channel DACs driver"
depends on (SPI_MASTER && I2C!=m) || I2C
@@ -68,7 +63,7 @@ config AD5446
module will be called ad5446.
config AD5449
- tristate "Analog Device AD5449 and similar DACs driver"
+ tristate "Analog Devices AD5449 and similar DACs driver"
depends on SPI_MASTER
help
Say yes here to build support for Analog Devices AD5415, AD5426, AD5429,
@@ -87,6 +82,24 @@ config AD5504
To compile this driver as a module, choose M here: the
module will be called ad5504.
+config AD5624R_SPI
+ tristate "Analog Devices AD5624/44/64R DAC spi driver"
+ depends on SPI
+ help
+ Say yes here to build support for Analog Devices AD5624R, AD5644R and
+ AD5664R converters (DAC). This driver uses the common SPI interface.
+
+config AD5686
+ tristate "Analog Devices AD5686R/AD5685R/AD5684R DAC SPI driver"
+ depends on SPI
+ help
+ Say yes here to build support for Analog Devices AD5686R, AD5685R,
+ AD5684R, AD5791 Voltage Output Digital to
+ Analog Converter.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ad5686.
+
config AD5755
tristate "Analog Devices AD5755/AD5755-1/AD5757/AD5735/AD5737 DAC driver"
depends on SPI_MASTER
@@ -119,19 +132,8 @@ config AD5791
To compile this driver as a module, choose M here: the
module will be called ad5791.
-config AD5686
- tristate "Analog Devices AD5686R/AD5685R/AD5684R DAC SPI driver"
- depends on SPI
- help
- Say yes here to build support for Analog Devices AD5686R, AD5685R,
- AD5684R, AD5791 Voltage Output Digital to
- Analog Converter.
-
- To compile this driver as a module, choose M here: the
- module will be called ad5686.
-
config AD7303
- tristate "Analog Devices Analog Devices AD7303 DAC driver"
+ tristate "Analog Devices AD7303 DAC driver"
depends on SPI
help
Say yes here to build support for Analog Devices AD7303 Digital to Analog
diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile
index c8d7ab6bff01..bb84ad64463f 100644
--- a/drivers/iio/dac/Makefile
+++ b/drivers/iio/dac/Makefile
@@ -2,6 +2,7 @@
# Makefile for industrial I/O DAC drivers
#
+# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_AD5360) += ad5360.o
obj-$(CONFIG_AD5380) += ad5380.o
obj-$(CONFIG_AD5421) += ad5421.o
diff --git a/drivers/iio/dac/mcp4725.c b/drivers/iio/dac/mcp4725.c
index a612ec766d96..1f4a48e6a82c 100644
--- a/drivers/iio/dac/mcp4725.c
+++ b/drivers/iio/dac/mcp4725.c
@@ -12,14 +12,13 @@
* driver for the Microchip I2C 12-bit digital-to-analog converter (DAC)
* (7-bit I2C slave address 0x60, the three LSBs can be configured in
* hardware)
- *
- * writing the DAC value to EEPROM is not supported
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/err.h>
+#include <linux/delay.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
@@ -32,15 +31,19 @@ struct mcp4725_data {
struct i2c_client *client;
u16 vref_mv;
u16 dac_value;
+ bool powerdown;
+ unsigned powerdown_mode;
};
-#ifdef CONFIG_PM_SLEEP
static int mcp4725_suspend(struct device *dev)
{
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct mcp4725_data *data = iio_priv(indio_dev);
u8 outbuf[2];
- outbuf[0] = 0x3 << 4; /* power-down bits, 500 kOhm resistor */
+ outbuf[0] = (data->powerdown_mode + 1) << 4;
outbuf[1] = 0;
+ data->powerdown = true;
return i2c_master_send(to_i2c_client(dev), outbuf, 2);
}
@@ -54,16 +57,150 @@ static int mcp4725_resume(struct device *dev)
/* restore previous DAC value */
outbuf[0] = (data->dac_value >> 8) & 0xf;
outbuf[1] = data->dac_value & 0xff;
+ data->powerdown = false;
return i2c_master_send(to_i2c_client(dev), outbuf, 2);
}
+#ifdef CONFIG_PM_SLEEP
static SIMPLE_DEV_PM_OPS(mcp4725_pm_ops, mcp4725_suspend, mcp4725_resume);
#define MCP4725_PM_OPS (&mcp4725_pm_ops)
#else
#define MCP4725_PM_OPS NULL
#endif
+static ssize_t mcp4725_store_eeprom(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t len)
+{
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct mcp4725_data *data = iio_priv(indio_dev);
+ int tries = 20;
+ u8 inoutbuf[3];
+ bool state;
+ int ret;
+
+ ret = strtobool(buf, &state);
+ if (ret < 0)
+ return ret;
+
+ if (!state)
+ return 0;
+
+ inoutbuf[0] = 0x60; /* write EEPROM */
+ inoutbuf[1] = data->dac_value >> 4;
+ inoutbuf[2] = (data->dac_value & 0xf) << 4;
+
+ ret = i2c_master_send(data->client, inoutbuf, 3);
+ if (ret < 0)
+ return ret;
+ else if (ret != 3)
+ return -EIO;
+
+ /* wait for write complete, takes up to 50ms */
+ while (tries--) {
+ msleep(20);
+ ret = i2c_master_recv(data->client, inoutbuf, 3);
+ if (ret < 0)
+ return ret;
+ else if (ret != 3)
+ return -EIO;
+
+ if (inoutbuf[0] & 0x80)
+ break;
+ }
+
+ if (tries < 0) {
+ dev_err(&data->client->dev,
+ "mcp4725_store_eeprom() failed, incomplete\n");
+ return -EIO;
+ }
+
+ return len;
+}
+
+static IIO_DEVICE_ATTR(store_eeprom, S_IWUSR, NULL, mcp4725_store_eeprom, 0);
+
+static struct attribute *mcp4725_attributes[] = {
+ &iio_dev_attr_store_eeprom.dev_attr.attr,
+ NULL,
+};
+
+static const struct attribute_group mcp4725_attribute_group = {
+ .attrs = mcp4725_attributes,
+};
+
+static const char * const mcp4725_powerdown_modes[] = {
+ "1kohm_to_gnd",
+ "100kohm_to_gnd",
+ "500kohm_to_gnd"
+};
+
+static int mcp4725_get_powerdown_mode(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan)
+{
+ struct mcp4725_data *data = iio_priv(indio_dev);
+
+ return data->powerdown_mode;
+}
+
+static int mcp4725_set_powerdown_mode(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan, unsigned mode)
+{
+ struct mcp4725_data *data = iio_priv(indio_dev);
+
+ data->powerdown_mode = mode;
+
+ return 0;
+}
+
+static ssize_t mcp4725_read_powerdown(struct iio_dev *indio_dev,
+ uintptr_t private, const struct iio_chan_spec *chan, char *buf)
+{
+ struct mcp4725_data *data = iio_priv(indio_dev);
+
+ return sprintf(buf, "%d\n", data->powerdown);
+}
+
+static ssize_t mcp4725_write_powerdown(struct iio_dev *indio_dev,
+ uintptr_t private, const struct iio_chan_spec *chan,
+ const char *buf, size_t len)
+{
+ struct mcp4725_data *data = iio_priv(indio_dev);
+ bool state;
+ int ret;
+
+ ret = strtobool(buf, &state);
+ if (ret)
+ return ret;
+
+ if (state)
+ ret = mcp4725_suspend(&data->client->dev);
+ else
+ ret = mcp4725_resume(&data->client->dev);
+ if (ret < 0)
+ return ret;
+
+ return len;
+}
+
+static const struct iio_enum mcp4725_powerdown_mode_enum = {
+ .items = mcp4725_powerdown_modes,
+ .num_items = ARRAY_SIZE(mcp4725_powerdown_modes),
+ .get = mcp4725_get_powerdown_mode,
+ .set = mcp4725_set_powerdown_mode,
+};
+
+static const struct iio_chan_spec_ext_info mcp4725_ext_info[] = {
+ {
+ .name = "powerdown",
+ .read = mcp4725_read_powerdown,
+ .write = mcp4725_write_powerdown,
+ },
+ IIO_ENUM("powerdown_mode", false, &mcp4725_powerdown_mode_enum),
+ IIO_ENUM_AVAILABLE("powerdown_mode", &mcp4725_powerdown_mode_enum),
+ { },
+};
+
static const struct iio_chan_spec mcp4725_channel = {
.type = IIO_VOLTAGE,
.indexed = 1,
@@ -72,6 +209,7 @@ static const struct iio_chan_spec mcp4725_channel = {
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
.scan_type = IIO_ST('u', 12, 16, 0),
+ .ext_info = mcp4725_ext_info,
};
static int mcp4725_set_value(struct iio_dev *indio_dev, int val)
@@ -138,6 +276,7 @@ static int mcp4725_write_raw(struct iio_dev *indio_dev,
static const struct iio_info mcp4725_info = {
.read_raw = mcp4725_read_raw,
.write_raw = mcp4725_write_raw,
+ .attrs = &mcp4725_attribute_group,
.driver_module = THIS_MODULE,
};
@@ -148,19 +287,17 @@ static int mcp4725_probe(struct i2c_client *client,
struct iio_dev *indio_dev;
struct mcp4725_platform_data *platform_data = client->dev.platform_data;
u8 inbuf[3];
+ u8 pd;
int err;
if (!platform_data || !platform_data->vref_mv) {
dev_err(&client->dev, "invalid platform data");
- err = -EINVAL;
- goto exit;
+ return -EINVAL;
}
- indio_dev = iio_device_alloc(sizeof(*data));
- if (indio_dev == NULL) {
- err = -ENOMEM;
- goto exit;
- }
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (indio_dev == NULL)
+ return -ENOMEM;
data = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev);
data->client = client;
@@ -177,31 +314,25 @@ static int mcp4725_probe(struct i2c_client *client,
err = i2c_master_recv(client, inbuf, 3);
if (err < 0) {
dev_err(&client->dev, "failed to read DAC value");
- goto exit_free_device;
+ return err;
}
+ pd = (inbuf[0] >> 1) & 0x3;
+ data->powerdown = pd > 0 ? true : false;
+ data->powerdown_mode = pd ? pd-1 : 2; /* 500kohm_to_gnd */
data->dac_value = (inbuf[1] << 4) | (inbuf[2] >> 4);
err = iio_device_register(indio_dev);
if (err)
- goto exit_free_device;
+ return err;
dev_info(&client->dev, "MCP4725 DAC registered\n");
return 0;
-
-exit_free_device:
- iio_device_free(indio_dev);
-exit:
- return err;
}
static int mcp4725_remove(struct i2c_client *client)
{
- struct iio_dev *indio_dev = i2c_get_clientdata(client);
-
- iio_device_unregister(indio_dev);
- iio_device_free(indio_dev);
-
+ iio_device_unregister(i2c_get_clientdata(client));
return 0;
}
diff --git a/drivers/iio/frequency/Kconfig b/drivers/iio/frequency/Kconfig
index 6aaa33ef4544..dc5e0b72882f 100644
--- a/drivers/iio/frequency/Kconfig
+++ b/drivers/iio/frequency/Kconfig
@@ -4,6 +4,7 @@
# Clock Distribution device drivers
# Phase-Locked Loop (PLL) frequency synthesizers
#
+# When adding new entries keep the list in alphabetical order
menu "Frequency Synthesizers DDS/PLL"
diff --git a/drivers/iio/frequency/Makefile b/drivers/iio/frequency/Makefile
index 00d26e5d1dc2..2bca03f3e2e3 100644
--- a/drivers/iio/frequency/Makefile
+++ b/drivers/iio/frequency/Makefile
@@ -2,5 +2,6 @@
# Makefile iio/frequency
#
+# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_AD9523) += ad9523.o
obj-$(CONFIG_ADF4350) += adf4350.o
diff --git a/drivers/iio/frequency/ad9523.c b/drivers/iio/frequency/ad9523.c
index 92276deeb026..7c5245d9f99c 100644
--- a/drivers/iio/frequency/ad9523.c
+++ b/drivers/iio/frequency/ad9523.c
@@ -961,17 +961,17 @@ static int ad9523_probe(struct spi_device *spi)
return -EINVAL;
}
- indio_dev = iio_device_alloc(sizeof(*st));
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
st = iio_priv(indio_dev);
- st->reg = regulator_get(&spi->dev, "vcc");
+ st->reg = devm_regulator_get(&spi->dev, "vcc");
if (!IS_ERR(st->reg)) {
ret = regulator_enable(st->reg);
if (ret)
- goto error_put_reg;
+ return ret;
}
spi_set_drvdata(spi, indio_dev);
@@ -1001,11 +1001,6 @@ static int ad9523_probe(struct spi_device *spi)
error_disable_reg:
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
-error_put_reg:
- if (!IS_ERR(st->reg))
- regulator_put(st->reg);
-
- iio_device_free(indio_dev);
return ret;
}
@@ -1017,12 +1012,8 @@ static int ad9523_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
- if (!IS_ERR(st->reg)) {
+ if (!IS_ERR(st->reg))
regulator_disable(st->reg);
- regulator_put(st->reg);
- }
-
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/iio/frequency/adf4350.c b/drivers/iio/frequency/adf4350.c
index a4157cdb314d..a7b30be86ae0 100644
--- a/drivers/iio/frequency/adf4350.c
+++ b/drivers/iio/frequency/adf4350.c
@@ -515,7 +515,7 @@ static int adf4350_probe(struct spi_device *spi)
}
if (!pdata->clkin) {
- clk = clk_get(&spi->dev, "clkin");
+ clk = devm_clk_get(&spi->dev, "clkin");
if (IS_ERR(clk))
return -EPROBE_DEFER;
@@ -524,17 +524,17 @@ static int adf4350_probe(struct spi_device *spi)
return ret;
}
- indio_dev = iio_device_alloc(sizeof(*st));
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
st = iio_priv(indio_dev);
- st->reg = regulator_get(&spi->dev, "vcc");
+ st->reg = devm_regulator_get(&spi->dev, "vcc");
if (!IS_ERR(st->reg)) {
ret = regulator_enable(st->reg);
if (ret)
- goto error_put_reg;
+ goto error_disable_clk;
}
spi_set_drvdata(spi, indio_dev);
@@ -564,7 +564,8 @@ static int adf4350_probe(struct spi_device *spi)
memset(st->regs_hw, 0xFF, sizeof(st->regs_hw));
if (gpio_is_valid(pdata->gpio_lock_detect)) {
- ret = gpio_request(pdata->gpio_lock_detect, indio_dev->name);
+ ret = devm_gpio_request(&spi->dev, pdata->gpio_lock_detect,
+ indio_dev->name);
if (ret) {
dev_err(&spi->dev, "fail to request lock detect GPIO-%d",
pdata->gpio_lock_detect);
@@ -576,29 +577,21 @@ static int adf4350_probe(struct spi_device *spi)
if (pdata->power_up_frequency) {
ret = adf4350_set_freq(st, pdata->power_up_frequency);
if (ret)
- goto error_free_gpio;
+ goto error_disable_reg;
}
ret = iio_device_register(indio_dev);
if (ret)
- goto error_free_gpio;
+ goto error_disable_reg;
return 0;
-error_free_gpio:
- if (gpio_is_valid(pdata->gpio_lock_detect))
- gpio_free(pdata->gpio_lock_detect);
-
error_disable_reg:
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
-error_put_reg:
- if (!IS_ERR(st->reg))
- regulator_put(st->reg);
-
+error_disable_clk:
if (clk)
clk_disable_unprepare(clk);
- iio_device_free(indio_dev);
return ret;
}
@@ -619,14 +612,8 @@ static int adf4350_remove(struct spi_device *spi)
if (!IS_ERR(reg)) {
regulator_disable(reg);
- regulator_put(reg);
}
- if (gpio_is_valid(st->pdata->gpio_lock_detect))
- gpio_free(st->pdata->gpio_lock_detect);
-
- iio_device_free(indio_dev);
-
return 0;
}
diff --git a/drivers/iio/gyro/Kconfig b/drivers/iio/gyro/Kconfig
index 8498e9dcda68..41c64a43bcab 100644
--- a/drivers/iio/gyro/Kconfig
+++ b/drivers/iio/gyro/Kconfig
@@ -1,6 +1,8 @@
#
# IIO Digital Gyroscope Sensor drivers configuration
#
+# When adding new entries keep the list in alphabetical order
+
menu "Digital gyroscope sensors"
config ADIS16080
@@ -26,6 +28,18 @@ config ADIS16136
Say yes here to build support for the Analog Devices ADIS16133, ADIS16135,
ADIS16136 gyroscope devices.
+config ADIS16260
+ tristate "Analog Devices ADIS16260 Digital Gyroscope Sensor SPI driver"
+ depends on SPI
+ select IIO_ADIS_LIB
+ select IIO_ADIS_LIB_BUFFER if IIO_BUFFER
+ help
+ Say yes here to build support for Analog Devices ADIS16260 ADIS16265
+ ADIS16250 ADIS16255 and ADIS16251 programmable digital gyroscope sensors.
+
+ This driver can also be built as a module. If so, the module
+ will be called adis16260.
+
config ADXRS450
tristate "Analog Devices ADXRS450/3 Digital Output Gyroscope SPI driver"
depends on SPI
@@ -58,8 +72,8 @@ config IIO_ST_GYRO_3AXIS
Say yes here to build support for STMicroelectronics gyroscopes:
L3G4200D, LSM330DL, L3GD20, L3GD20H, LSM330DLC, L3G4IS, LSM330.
- This driver can also be built as a module. If so, will be created
- these modules:
+ This driver can also be built as a module. If so, these modules
+ will be created:
- st_gyro (core functions for the driver [it is mandatory]);
- st_gyro_i2c (necessary for the I2C devices [optional*]);
- st_gyro_spi (necessary for the SPI devices [optional*]);
diff --git a/drivers/iio/gyro/Makefile b/drivers/iio/gyro/Makefile
index e9dc034aa18b..2f2752a4ea83 100644
--- a/drivers/iio/gyro/Makefile
+++ b/drivers/iio/gyro/Makefile
@@ -2,9 +2,11 @@
# Makefile for industrial I/O gyroscope sensor drivers
#
+# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_ADIS16080) += adis16080.o
obj-$(CONFIG_ADIS16130) += adis16130.o
obj-$(CONFIG_ADIS16136) += adis16136.o
+obj-$(CONFIG_ADIS16260) += adis16260.o
obj-$(CONFIG_ADXRS450) += adxrs450.o
obj-$(CONFIG_HID_SENSOR_GYRO_3D) += hid-sensor-gyro-3d.o
diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/iio/gyro/adis16260.c
index 620d63fd099b..b4cf800717ad 100644
--- a/drivers/staging/iio/gyro/adis16260_core.c
+++ b/drivers/iio/gyro/adis16260.c
@@ -7,54 +7,119 @@
*/
#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 <linux/iio/imu/adis.h>
+
+#define ADIS16260_STARTUP_DELAY 220 /* ms */
+
+#define ADIS16260_FLASH_CNT 0x00 /* Flash memory write count */
+#define ADIS16260_SUPPLY_OUT 0x02 /* Power supply measurement */
+#define ADIS16260_GYRO_OUT 0x04 /* X-axis gyroscope output */
+#define ADIS16260_AUX_ADC 0x0A /* analog input channel measurement */
+#define ADIS16260_TEMP_OUT 0x0C /* internal temperature measurement */
+#define ADIS16260_ANGL_OUT 0x0E /* angle displacement */
+#define ADIS16260_GYRO_OFF 0x14 /* Calibration, offset/bias adjustment */
+#define ADIS16260_GYRO_SCALE 0x16 /* Calibration, scale adjustment */
+#define ADIS16260_ALM_MAG1 0x20 /* Alarm 1 magnitude/polarity setting */
+#define ADIS16260_ALM_MAG2 0x22 /* Alarm 2 magnitude/polarity setting */
+#define ADIS16260_ALM_SMPL1 0x24 /* Alarm 1 dynamic rate of change setting */
+#define ADIS16260_ALM_SMPL2 0x26 /* Alarm 2 dynamic rate of change setting */
+#define ADIS16260_ALM_CTRL 0x28 /* Alarm control */
+#define ADIS16260_AUX_DAC 0x30 /* Auxiliary DAC data */
+#define ADIS16260_GPIO_CTRL 0x32 /* Control, digital I/O line */
+#define ADIS16260_MSC_CTRL 0x34 /* Control, data ready, self-test settings */
+#define ADIS16260_SMPL_PRD 0x36 /* Control, internal sample rate */
+#define ADIS16260_SENS_AVG 0x38 /* Control, dynamic range, filtering */
+#define ADIS16260_SLP_CNT 0x3A /* Control, sleep mode initiation */
+#define ADIS16260_DIAG_STAT 0x3C /* Diagnostic, error flags */
+#define ADIS16260_GLOB_CMD 0x3E /* Control, global commands */
+#define ADIS16260_LOT_ID1 0x52 /* Lot Identification Code 1 */
+#define ADIS16260_LOT_ID2 0x54 /* Lot Identification Code 2 */
+#define ADIS16260_PROD_ID 0x56 /* Product identifier;
+ * convert to decimal = 16,265/16,260 */
+#define ADIS16260_SERIAL_NUM 0x58 /* Serial number */
+
+#define ADIS16260_ERROR_ACTIVE (1<<14)
+#define ADIS16260_NEW_DATA (1<<15)
+
+/* MSC_CTRL */
+#define ADIS16260_MSC_CTRL_MEM_TEST (1<<11)
+/* Internal self-test enable */
+#define ADIS16260_MSC_CTRL_INT_SELF_TEST (1<<10)
+#define ADIS16260_MSC_CTRL_NEG_SELF_TEST (1<<9)
+#define ADIS16260_MSC_CTRL_POS_SELF_TEST (1<<8)
+#define ADIS16260_MSC_CTRL_DATA_RDY_EN (1<<2)
+#define ADIS16260_MSC_CTRL_DATA_RDY_POL_HIGH (1<<1)
+#define ADIS16260_MSC_CTRL_DATA_RDY_DIO2 (1<<0)
+
+/* SMPL_PRD */
+/* Time base (tB): 0 = 1.953 ms, 1 = 60.54 ms */
+#define ADIS16260_SMPL_PRD_TIME_BASE (1<<7)
+#define ADIS16260_SMPL_PRD_DIV_MASK 0x7F
+
+/* SLP_CNT */
+#define ADIS16260_SLP_CNT_POWER_OFF 0x80
+
+/* DIAG_STAT */
+#define ADIS16260_DIAG_STAT_ALARM2 (1<<9)
+#define ADIS16260_DIAG_STAT_ALARM1 (1<<8)
+#define ADIS16260_DIAG_STAT_FLASH_CHK_BIT 6
+#define ADIS16260_DIAG_STAT_SELF_TEST_BIT 5
+#define ADIS16260_DIAG_STAT_OVERFLOW_BIT 4
+#define ADIS16260_DIAG_STAT_SPI_FAIL_BIT 3
+#define ADIS16260_DIAG_STAT_FLASH_UPT_BIT 2
+#define ADIS16260_DIAG_STAT_POWER_HIGH_BIT 1
+#define ADIS16260_DIAG_STAT_POWER_LOW_BIT 0
+
+/* GLOB_CMD */
+#define ADIS16260_GLOB_CMD_SW_RESET (1<<7)
+#define ADIS16260_GLOB_CMD_FLASH_UPD (1<<3)
+#define ADIS16260_GLOB_CMD_DAC_LATCH (1<<2)
+#define ADIS16260_GLOB_CMD_FAC_CALIB (1<<1)
+#define ADIS16260_GLOB_CMD_AUTO_NULL (1<<0)
+
+#define ADIS16260_SPI_SLOW (u32)(300 * 1000)
+#define ADIS16260_SPI_BURST (u32)(1000 * 1000)
+#define ADIS16260_SPI_FAST (u32)(2000 * 1000)
+
+/* At the moment triggers are only used for ring buffer
+ * filling. This may change!
+ */
-#include "adis16260.h"
-
-static ssize_t adis16260_read_frequency_available(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct adis16260_state *st = iio_priv(indio_dev);
- if (spi_get_device_id(st->adis.spi)->driver_data)
- return sprintf(buf, "%s\n", "0.129 ~ 256");
- else
- return sprintf(buf, "%s\n", "256 2048");
-}
+#define ADIS16260_SCAN_GYRO 0
+#define ADIS16260_SCAN_SUPPLY 1
+#define ADIS16260_SCAN_AUX_ADC 2
+#define ADIS16260_SCAN_TEMP 3
+#define ADIS16260_SCAN_ANGL 4
static ssize_t adis16260_read_frequency(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct adis16260_state *st = iio_priv(indio_dev);
+ struct adis *adis = iio_priv(indio_dev);
int ret, len = 0;
u16 t;
int sps;
- ret = adis_read_reg_16(&st->adis, ADIS16260_SMPL_PRD, &t);
+ ret = adis_read_reg_16(adis, ADIS16260_SMPL_PRD, &t);
if (ret)
return ret;
- if (spi_get_device_id(st->adis.spi)->driver_data) /* If an adis16251 */
- sps = (t & ADIS16260_SMPL_PRD_TIME_BASE) ? 8 : 256;
+ if (spi_get_device_id(adis->spi)->driver_data) /* If an adis16251 */
+ sps = (t & ADIS16260_SMPL_PRD_TIME_BASE) ? 8 : 256;
else
- sps = (t & ADIS16260_SMPL_PRD_TIME_BASE) ? 66 : 2048;
+ sps = (t & ADIS16260_SMPL_PRD_TIME_BASE) ? 66 : 2048;
sps /= (t & ADIS16260_SMPL_PRD_DIV_MASK) + 1;
- len = sprintf(buf, "%d SPS\n", sps);
+ len = sprintf(buf, "%d\n", sps);
return len;
}
@@ -64,36 +129,31 @@ static ssize_t adis16260_write_frequency(struct device *dev,
size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct adis16260_state *st = iio_priv(indio_dev);
- long val;
+ struct adis *adis = iio_priv(indio_dev);
+ unsigned int val;
int ret;
u8 t;
- ret = strict_strtol(buf, 10, &val);
+ ret = kstrtouint(buf, 10, &val);
if (ret)
return ret;
- if (val == 0)
- return -EINVAL;
mutex_lock(&indio_dev->mlock);
- if (spi_get_device_id(st->adis.spi)->driver_data) {
- t = (256 / val);
- if (t > 0)
- t--;
- t &= ADIS16260_SMPL_PRD_DIV_MASK;
- } else {
- t = (2048 / val);
- if (t > 0)
- t--;
- t &= ADIS16260_SMPL_PRD_DIV_MASK;
- }
- if ((t & ADIS16260_SMPL_PRD_DIV_MASK) >= 0x0A)
- st->adis.spi->max_speed_hz = ADIS16260_SPI_SLOW;
+ if (spi_get_device_id(adis->spi)->driver_data)
+ t = 256 / val;
+ else
+ t = 2048 / val;
+
+ if (t > ADIS16260_SMPL_PRD_DIV_MASK)
+ t = ADIS16260_SMPL_PRD_DIV_MASK;
+ else if (t > 0)
+ t--;
+
+ if (t >= 0x0A)
+ adis->spi->max_speed_hz = ADIS16260_SPI_SLOW;
else
- st->adis.spi->max_speed_hz = ADIS16260_SPI_FAST;
- ret = adis_write_reg_8(&st->adis,
- ADIS16260_SMPL_PRD,
- t);
+ adis->spi->max_speed_hz = ADIS16260_SPI_FAST;
+ ret = adis_write_reg_8(adis, ADIS16260_SMPL_PRD, t);
mutex_unlock(&indio_dev->mlock);
@@ -103,11 +163,11 @@ static ssize_t adis16260_write_frequency(struct device *dev,
/* Power down the device */
static int adis16260_stop_device(struct iio_dev *indio_dev)
{
- struct adis16260_state *st = iio_priv(indio_dev);
+ struct adis *adis = iio_priv(indio_dev);
int ret;
u16 val = ADIS16260_SLP_CNT_POWER_OFF;
- ret = adis_write_reg_16(&st->adis, ADIS16260_SLP_CNT, val);
+ ret = adis_write_reg_16(adis, ADIS16260_SLP_CNT, val);
if (ret)
dev_err(&indio_dev->dev, "problem with turning device off: SLP_CNT");
@@ -118,24 +178,16 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
adis16260_read_frequency,
adis16260_write_frequency);
-static IIO_DEVICE_ATTR(sampling_frequency_available,
- S_IRUGO, adis16260_read_frequency_available, NULL, 0);
-
-#define ADIS16260_GYRO_CHANNEL_SET(axis, mod) \
-struct iio_chan_spec adis16260_channels_##axis[] = { \
- ADIS_GYRO_CHAN(mod, ADIS16260_GYRO_OUT, ADIS16260_SCAN_GYRO, \
- BIT(IIO_CHAN_INFO_CALIBBIAS) | \
- BIT(IIO_CHAN_INFO_CALIBSCALE), 14), \
- ADIS_INCLI_CHAN(mod, ADIS16260_ANGL_OUT, ADIS16260_SCAN_ANGL, 0, 14), \
- ADIS_TEMP_CHAN(ADIS16260_TEMP_OUT, ADIS16260_SCAN_TEMP, 12), \
- ADIS_SUPPLY_CHAN(ADIS16260_SUPPLY_OUT, ADIS16260_SCAN_SUPPLY, 12), \
- ADIS_AUX_ADC_CHAN(ADIS16260_AUX_ADC, ADIS16260_SCAN_AUX_ADC, 12), \
- IIO_CHAN_SOFT_TIMESTAMP(5), \
-}
-
-static const ADIS16260_GYRO_CHANNEL_SET(x, X);
-static const ADIS16260_GYRO_CHANNEL_SET(y, Y);
-static const ADIS16260_GYRO_CHANNEL_SET(z, Z);
+static const struct iio_chan_spec adis16260_channels[] = {
+ ADIS_GYRO_CHAN(X, ADIS16260_GYRO_OUT, ADIS16260_SCAN_GYRO,
+ BIT(IIO_CHAN_INFO_CALIBBIAS) |
+ BIT(IIO_CHAN_INFO_CALIBSCALE), 14),
+ ADIS_INCLI_CHAN(X, ADIS16260_ANGL_OUT, ADIS16260_SCAN_ANGL, 0, 14),
+ ADIS_TEMP_CHAN(ADIS16260_TEMP_OUT, ADIS16260_SCAN_TEMP, 12),
+ ADIS_SUPPLY_CHAN(ADIS16260_SUPPLY_OUT, ADIS16260_SCAN_SUPPLY, 12),
+ ADIS_AUX_ADC_CHAN(ADIS16260_AUX_ADC, ADIS16260_SCAN_AUX_ADC, 12),
+ IIO_CHAN_SOFT_TIMESTAMP(5),
+};
static const u8 adis16260_addresses[][2] = {
[ADIS16260_SCAN_GYRO] = { ADIS16260_GYRO_OFF, ADIS16260_GYRO_SCALE },
@@ -146,9 +198,8 @@ static int adis16260_read_raw(struct iio_dev *indio_dev,
int *val, int *val2,
long mask)
{
- struct adis16260_state *st = iio_priv(indio_dev);
+ struct adis *adis = iio_priv(indio_dev);
int ret;
- int bits;
u8 addr;
s16 val16;
@@ -160,7 +211,7 @@ static int adis16260_read_raw(struct iio_dev *indio_dev,
switch (chan->type) {
case IIO_ANGL_VEL:
*val = 0;
- if (spi_get_device_id(st->adis.spi)->driver_data) {
+ if (spi_get_device_id(adis->spi)->driver_data) {
/* 0.01832 degree / sec */
*val2 = IIO_DEGREE_TO_RAD(18320);
} else {
@@ -168,6 +219,10 @@ static int adis16260_read_raw(struct iio_dev *indio_dev,
*val2 = IIO_DEGREE_TO_RAD(73260);
}
return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_INCLI:
+ *val = 0;
+ *val2 = IIO_DEGREE_TO_RAD(36630);
+ return IIO_VAL_INT_PLUS_MICRO;
case IIO_VOLTAGE:
if (chan->channel == 0) {
*val = 1;
@@ -189,42 +244,20 @@ static int adis16260_read_raw(struct iio_dev *indio_dev,
*val = 250000 / 1453; /* 25 C = 0x00 */
return IIO_VAL_INT;
case IIO_CHAN_INFO_CALIBBIAS:
- switch (chan->type) {
- case IIO_ANGL_VEL:
- bits = 12;
- break;
- default:
- return -EINVAL;
- }
- mutex_lock(&indio_dev->mlock);
addr = adis16260_addresses[chan->scan_index][0];
- ret = adis_read_reg_16(&st->adis, addr, &val16);
- if (ret) {
- mutex_unlock(&indio_dev->mlock);
+ ret = adis_read_reg_16(adis, addr, &val16);
+ if (ret)
return ret;
- }
- val16 &= (1 << bits) - 1;
- val16 = (s16)(val16 << (16 - bits)) >> (16 - bits);
- *val = val16;
- mutex_unlock(&indio_dev->mlock);
+
+ *val = sign_extend32(val16, 11);
return IIO_VAL_INT;
case IIO_CHAN_INFO_CALIBSCALE:
- switch (chan->type) {
- case IIO_ANGL_VEL:
- bits = 12;
- break;
- default:
- return -EINVAL;
- }
- mutex_lock(&indio_dev->mlock);
addr = adis16260_addresses[chan->scan_index][1];
- ret = adis_read_reg_16(&st->adis, addr, &val16);
- if (ret) {
- mutex_unlock(&indio_dev->mlock);
+ ret = adis_read_reg_16(adis, addr, &val16);
+ if (ret)
return ret;
- }
- *val = (1 << bits) - 1;
- mutex_unlock(&indio_dev->mlock);
+
+ *val = val16;
return IIO_VAL_INT;
}
return -EINVAL;
@@ -236,26 +269,28 @@ static int adis16260_write_raw(struct iio_dev *indio_dev,
int val2,
long mask)
{
- struct adis16260_state *st = iio_priv(indio_dev);
- int bits = 12;
- s16 val16;
+ struct adis *adis = iio_priv(indio_dev);
u8 addr;
+
switch (mask) {
case IIO_CHAN_INFO_CALIBBIAS:
- val16 = val & ((1 << bits) - 1);
+ if (val < -2048 || val >= 2048)
+ return -EINVAL;
+
addr = adis16260_addresses[chan->scan_index][0];
- return adis_write_reg_16(&st->adis, addr, val16);
+ return adis_write_reg_16(adis, addr, val);
case IIO_CHAN_INFO_CALIBSCALE:
- val16 = val & ((1 << bits) - 1);
+ if (val < 0 || val >= 4096)
+ return -EINVAL;
+
addr = adis16260_addresses[chan->scan_index][1];
- return adis_write_reg_16(&st->adis, addr, val16);
+ return adis_write_reg_16(adis, addr, val);
}
return -EINVAL;
}
static struct attribute *adis16260_attributes[] = {
&iio_dev_attr_sampling_frequency.dev_attr.attr,
- &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
NULL
};
@@ -303,71 +338,37 @@ static const struct adis_data adis16260_data = {
static int adis16260_probe(struct spi_device *spi)
{
- int ret;
- struct adis16260_platform_data *pd = spi->dev.platform_data;
- struct adis16260_state *st;
struct iio_dev *indio_dev;
+ struct adis *adis;
+ int ret;
/* setup the industrialio driver allocated elements */
- indio_dev = iio_device_alloc(sizeof(*st));
+ indio_dev = iio_device_alloc(sizeof(*adis));
if (indio_dev == NULL) {
ret = -ENOMEM;
goto error_ret;
}
- st = iio_priv(indio_dev);
- if (pd)
- st->negate = pd->negate;
+ adis = iio_priv(indio_dev);
/* this is only used for removal purposes */
spi_set_drvdata(spi, indio_dev);
indio_dev->name = spi_get_device_id(spi)->name;
indio_dev->dev.parent = &spi->dev;
indio_dev->info = &adis16260_info;
- indio_dev->num_channels
- = ARRAY_SIZE(adis16260_channels_x);
- if (pd && pd->direction)
- switch (pd->direction) {
- case 'x':
- indio_dev->channels = adis16260_channels_x;
- break;
- case 'y':
- indio_dev->channels = adis16260_channels_y;
- break;
- case 'z':
- indio_dev->channels = adis16260_channels_z;
- break;
- default:
- return -EINVAL;
- }
- else
- indio_dev->channels = adis16260_channels_x;
- indio_dev->num_channels = ARRAY_SIZE(adis16260_channels_x);
+ indio_dev->channels = adis16260_channels;
+ indio_dev->num_channels = ARRAY_SIZE(adis16260_channels);
indio_dev->modes = INDIO_DIRECT_MODE;
- ret = adis_init(&st->adis, indio_dev, spi, &adis16260_data);
+ ret = adis_init(adis, indio_dev, spi, &adis16260_data);
if (ret)
goto error_free_dev;
- ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL);
+ ret = adis_setup_buffer_and_trigger(adis, indio_dev, NULL);
if (ret)
goto error_free_dev;
- if (indio_dev->buffer) {
- /* Set default scan mode */
- iio_scan_mask_set(indio_dev, indio_dev->buffer,
- ADIS16260_SCAN_SUPPLY);
- iio_scan_mask_set(indio_dev, indio_dev->buffer,
- ADIS16260_SCAN_GYRO);
- iio_scan_mask_set(indio_dev, indio_dev->buffer,
- ADIS16260_SCAN_AUX_ADC);
- iio_scan_mask_set(indio_dev, indio_dev->buffer,
- ADIS16260_SCAN_TEMP);
- iio_scan_mask_set(indio_dev, indio_dev->buffer,
- ADIS16260_SCAN_ANGL);
- }
-
/* Get the device into a sane initial state */
- ret = adis_initial_startup(&st->adis);
+ ret = adis_initial_startup(adis);
if (ret)
goto error_cleanup_buffer_trigger;
ret = iio_device_register(indio_dev);
@@ -377,7 +378,7 @@ static int adis16260_probe(struct spi_device *spi)
return 0;
error_cleanup_buffer_trigger:
- adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
+ adis_cleanup_buffer_and_trigger(adis, indio_dev);
error_free_dev:
iio_device_free(indio_dev);
error_ret:
@@ -387,11 +388,11 @@ error_ret:
static int adis16260_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
- struct adis16260_state *st = iio_priv(indio_dev);
+ struct adis *adis = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
adis16260_stop_device(indio_dev);
- adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
+ adis_cleanup_buffer_and_trigger(adis, indio_dev);
iio_device_free(indio_dev);
return 0;
diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c
index bc943dd47da5..9cc8aa1102d7 100644
--- a/drivers/iio/gyro/hid-sensor-gyro-3d.c
+++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c
@@ -30,10 +30,6 @@
#include <linux/iio/triggered_buffer.h>
#include "../common/hid-sensors/hid-sensor-trigger.h"
-/*Format: HID-SENSOR-usage_id_in_hex*/
-/*Usage ID from spec for Gyro-3D: 0x200076*/
-#define DRIVER_NAME "HID-SENSOR-200076"
-
enum gyro_3d_channel {
CHANNEL_SCAN_INDEX_X,
CHANNEL_SCAN_INDEX_Y,
@@ -389,9 +385,19 @@ static int hid_gyro_3d_remove(struct platform_device *pdev)
return 0;
}
+static struct platform_device_id hid_gyro_3d_ids[] = {
+ {
+ /* Format: HID-SENSOR-usage_id_in_hex_lowercase */
+ .name = "HID-SENSOR-200076",
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, hid_gyro_3d_ids);
+
static struct platform_driver hid_gyro_3d_platform_driver = {
+ .id_table = hid_gyro_3d_ids,
.driver = {
- .name = DRIVER_NAME,
+ .name = KBUILD_MODNAME,
.owner = THIS_MODULE,
},
.probe = hid_gyro_3d_probe,
diff --git a/drivers/iio/gyro/st_gyro.h b/drivers/iio/gyro/st_gyro.h
index 3ad9907bb154..f8f2bf84a5a2 100644
--- a/drivers/iio/gyro/st_gyro.h
+++ b/drivers/iio/gyro/st_gyro.h
@@ -23,7 +23,16 @@
#define L3G4IS_GYRO_DEV_NAME "l3g4is_ui"
#define LSM330_GYRO_DEV_NAME "lsm330_gyro"
-int st_gyro_common_probe(struct iio_dev *indio_dev);
+/**
+ * struct st_sensors_platform_data - gyro platform data
+ * @drdy_int_pin: DRDY on gyros is available only on INT2 pin.
+ */
+static const struct st_sensors_platform_data gyro_pdata = {
+ .drdy_int_pin = 2,
+};
+
+int st_gyro_common_probe(struct iio_dev *indio_dev,
+ struct st_sensors_platform_data *pdata);
void st_gyro_common_remove(struct iio_dev *indio_dev);
#ifdef CONFIG_IIO_BUFFER
diff --git a/drivers/iio/gyro/st_gyro_core.c b/drivers/iio/gyro/st_gyro_core.c
index f9ed3488c314..85fa8d343bb2 100644
--- a/drivers/iio/gyro/st_gyro_core.c
+++ b/drivers/iio/gyro/st_gyro_core.c
@@ -60,7 +60,7 @@
#define ST_GYRO_1_BDU_ADDR 0x23
#define ST_GYRO_1_BDU_MASK 0x80
#define ST_GYRO_1_DRDY_IRQ_ADDR 0x22
-#define ST_GYRO_1_DRDY_IRQ_MASK 0x08
+#define ST_GYRO_1_DRDY_IRQ_INT2_MASK 0x08
#define ST_GYRO_1_MULTIREAD_BIT true
/* CUSTOM VALUES FOR SENSOR 2 */
@@ -84,7 +84,7 @@
#define ST_GYRO_2_BDU_ADDR 0x23
#define ST_GYRO_2_BDU_MASK 0x80
#define ST_GYRO_2_DRDY_IRQ_ADDR 0x22
-#define ST_GYRO_2_DRDY_IRQ_MASK 0x08
+#define ST_GYRO_2_DRDY_IRQ_INT2_MASK 0x08
#define ST_GYRO_2_MULTIREAD_BIT true
static const struct iio_chan_spec st_gyro_16bit_channels[] = {
@@ -158,7 +158,7 @@ static const struct st_sensors st_gyro_sensors[] = {
},
.drdy_irq = {
.addr = ST_GYRO_1_DRDY_IRQ_ADDR,
- .mask = ST_GYRO_1_DRDY_IRQ_MASK,
+ .mask_int2 = ST_GYRO_1_DRDY_IRQ_INT2_MASK,
},
.multi_read_bit = ST_GYRO_1_MULTIREAD_BIT,
.bootime = 2,
@@ -221,7 +221,7 @@ static const struct st_sensors st_gyro_sensors[] = {
},
.drdy_irq = {
.addr = ST_GYRO_2_DRDY_IRQ_ADDR,
- .mask = ST_GYRO_2_DRDY_IRQ_MASK,
+ .mask_int2 = ST_GYRO_2_DRDY_IRQ_INT2_MASK,
},
.multi_read_bit = ST_GYRO_2_MULTIREAD_BIT,
.bootime = 2,
@@ -302,7 +302,8 @@ static const struct iio_trigger_ops st_gyro_trigger_ops = {
#define ST_GYRO_TRIGGER_OPS NULL
#endif
-int st_gyro_common_probe(struct iio_dev *indio_dev)
+int st_gyro_common_probe(struct iio_dev *indio_dev,
+ struct st_sensors_platform_data *pdata)
{
int err;
struct st_sensor_data *gdata = iio_priv(indio_dev);
@@ -324,7 +325,7 @@ int st_gyro_common_probe(struct iio_dev *indio_dev)
&gdata->sensor->fs.fs_avl[0];
gdata->odr = gdata->sensor->odr.odr_avl[0].hz;
- err = st_sensors_init_sensor(indio_dev);
+ err = st_sensors_init_sensor(indio_dev, pdata);
if (err < 0)
goto st_gyro_common_probe_error;
diff --git a/drivers/iio/gyro/st_gyro_i2c.c b/drivers/iio/gyro/st_gyro_i2c.c
index 8a310500573d..c7a29a4d7e82 100644
--- a/drivers/iio/gyro/st_gyro_i2c.c
+++ b/drivers/iio/gyro/st_gyro_i2c.c
@@ -36,7 +36,8 @@ static int st_gyro_i2c_probe(struct i2c_client *client,
st_sensors_i2c_configure(indio_dev, client, gdata);
- err = st_gyro_common_probe(indio_dev);
+ err = st_gyro_common_probe(indio_dev,
+ (struct st_sensors_platform_data *)&gyro_pdata);
if (err < 0)
goto st_gyro_common_probe_error;
diff --git a/drivers/iio/gyro/st_gyro_spi.c b/drivers/iio/gyro/st_gyro_spi.c
index f3540390eb22..14b0762847f5 100644
--- a/drivers/iio/gyro/st_gyro_spi.c
+++ b/drivers/iio/gyro/st_gyro_spi.c
@@ -35,7 +35,8 @@ static int st_gyro_spi_probe(struct spi_device *spi)
st_sensors_spi_configure(indio_dev, spi, gdata);
- err = st_gyro_common_probe(indio_dev);
+ err = st_gyro_common_probe(indio_dev,
+ (struct st_sensors_platform_data *)&gyro_pdata);
if (err < 0)
goto st_gyro_common_probe_error;
diff --git a/drivers/iio/iio_core_trigger.h b/drivers/iio/iio_core_trigger.h
index 6f7c56fcbe78..1fdb1e4ea4a5 100644
--- a/drivers/iio/iio_core_trigger.h
+++ b/drivers/iio/iio_core_trigger.h
@@ -30,7 +30,7 @@ void iio_device_unregister_trigger_consumer(struct iio_dev *indio_dev);
static int iio_device_register_trigger_consumer(struct iio_dev *indio_dev)
{
return 0;
-};
+}
/**
* iio_device_unregister_trigger_consumer() - reverse the registration process
@@ -38,9 +38,6 @@ static int iio_device_register_trigger_consumer(struct iio_dev *indio_dev)
**/
static void iio_device_unregister_trigger_consumer(struct iio_dev *indio_dev)
{
-};
+}
#endif /* CONFIG_TRIGGER_CONSUMER */
-
-
-
diff --git a/drivers/iio/imu/Kconfig b/drivers/iio/imu/Kconfig
index 4f40a10cb74f..663e88a1a3c1 100644
--- a/drivers/iio/imu/Kconfig
+++ b/drivers/iio/imu/Kconfig
@@ -1,6 +1,8 @@
#
# IIO imu drivers configuration
#
+# When adding new entries keep the list in alphabetical order
+
menu "Inertial measurement units"
config ADIS16400
diff --git a/drivers/iio/imu/Makefile b/drivers/iio/imu/Makefile
index f2f56ceaed26..114d2c17cbe2 100644
--- a/drivers/iio/imu/Makefile
+++ b/drivers/iio/imu/Makefile
@@ -2,6 +2,7 @@
# Makefile for Inertial Measurement Units
#
+# When adding new entries keep the list in alphabetical order
adis16400-y := adis16400_core.o
adis16400-$(CONFIG_IIO_BUFFER) += adis16400_buffer.o
obj-$(CONFIG_ADIS16400) += adis16400.o
diff --git a/drivers/iio/imu/adis16400_core.c b/drivers/iio/imu/adis16400_core.c
index f60591f0b925..3fb7757a1028 100644
--- a/drivers/iio/imu/adis16400_core.c
+++ b/drivers/iio/imu/adis16400_core.c
@@ -871,7 +871,7 @@ static int adis16400_probe(struct spi_device *spi)
struct iio_dev *indio_dev;
int ret;
- indio_dev = iio_device_alloc(sizeof(*st));
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
@@ -893,12 +893,12 @@ static int adis16400_probe(struct spi_device *spi)
ret = adis_init(&st->adis, indio_dev, spi, &adis16400_data);
if (ret)
- goto error_free_dev;
+ return ret;
ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev,
adis16400_trigger_handler);
if (ret)
- goto error_free_dev;
+ return ret;
/* Get the device into a sane initial state */
ret = adis16400_initial_setup(indio_dev);
@@ -913,8 +913,6 @@ static int adis16400_probe(struct spi_device *spi)
error_cleanup_buffer:
adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
-error_free_dev:
- iio_device_free(indio_dev);
return ret;
}
@@ -928,8 +926,6 @@ static int adis16400_remove(struct spi_device *spi)
adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
- iio_device_free(indio_dev);
-
return 0;
}
diff --git a/drivers/iio/imu/adis16480.c b/drivers/iio/imu/adis16480.c
index b7db38376295..dd4206cac62d 100644
--- a/drivers/iio/imu/adis16480.c
+++ b/drivers/iio/imu/adis16480.c
@@ -839,7 +839,7 @@ static int adis16480_probe(struct spi_device *spi)
struct adis16480 *st;
int ret;
- indio_dev = iio_device_alloc(sizeof(*st));
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
@@ -857,11 +857,11 @@ static int adis16480_probe(struct spi_device *spi)
ret = adis_init(&st->adis, indio_dev, spi, &adis16480_data);
if (ret)
- goto error_free_dev;
+ return ret;
ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL);
if (ret)
- goto error_free_dev;
+ return ret;
ret = adis16480_initial_setup(indio_dev);
if (ret)
@@ -879,8 +879,6 @@ error_stop_device:
adis16480_stop_device(indio_dev);
error_cleanup_buffer:
adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
-error_free_dev:
- iio_device_free(indio_dev);
return ret;
}
@@ -894,8 +892,6 @@ static int adis16480_remove(struct spi_device *spi)
adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
- iio_device_free(indio_dev);
-
return 0;
}
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
index fe4c61e219f3..df7f1e1157ae 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
@@ -23,6 +23,7 @@
#include <linux/interrupt.h>
#include <linux/kfifo.h>
#include <linux/spinlock.h>
+#include <linux/iio/iio.h>
#include "inv_mpu_iio.h"
/*
@@ -663,16 +664,13 @@ static int inv_mpu_probe(struct i2c_client *client,
int result;
if (!i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_READ_I2C_BLOCK |
- I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) {
- result = -ENOSYS;
- goto out_no_free;
- }
- indio_dev = iio_device_alloc(sizeof(*st));
- if (indio_dev == NULL) {
- result = -ENOMEM;
- goto out_no_free;
- }
+ I2C_FUNC_SMBUS_I2C_BLOCK))
+ return -ENOSYS;
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
+ if (!indio_dev)
+ return -ENOMEM;
+
st = iio_priv(indio_dev);
st->client = client;
st->plat_data = *(struct inv_mpu6050_platform_data
@@ -680,13 +678,13 @@ static int inv_mpu_probe(struct i2c_client *client,
/* power is turned on inside check chip type*/
result = inv_check_and_setup_chip(st, id);
if (result)
- goto out_free;
+ return result;
result = inv_mpu6050_init_config(indio_dev);
if (result) {
dev_err(&client->dev,
"Could not initialize device.\n");
- goto out_free;
+ return result;
}
i2c_set_clientdata(client, indio_dev);
@@ -705,7 +703,7 @@ static int inv_mpu_probe(struct i2c_client *client,
if (result) {
dev_err(&st->client->dev, "configure buffer fail %d\n",
result);
- goto out_free;
+ return result;
}
result = inv_mpu6050_probe_trigger(indio_dev);
if (result) {
@@ -727,10 +725,6 @@ out_remove_trigger:
inv_mpu6050_remove_trigger(st);
out_unreg_ring:
iio_triggered_buffer_cleanup(indio_dev);
-out_free:
- iio_device_free(indio_dev);
-out_no_free:
-
return result;
}
@@ -742,7 +736,6 @@ static int inv_mpu_remove(struct i2c_client *client)
iio_device_unregister(indio_dev);
inv_mpu6050_remove_trigger(st);
iio_triggered_buffer_cleanup(indio_dev);
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index e145931ef1b8..97f0297b120f 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -383,14 +383,14 @@ static ssize_t iio_read_channel_info(struct device *dev,
scale_db = true;
case IIO_VAL_INT_PLUS_MICRO:
if (val2 < 0)
- return sprintf(buf, "-%d.%06u%s\n", val, -val2,
+ return sprintf(buf, "-%ld.%06u%s\n", abs(val), -val2,
scale_db ? " dB" : "");
else
return sprintf(buf, "%d.%06u%s\n", val, val2,
scale_db ? " dB" : "");
case IIO_VAL_INT_PLUS_NANO:
if (val2 < 0)
- return sprintf(buf, "-%d.%09u\n", val, -val2);
+ return sprintf(buf, "-%ld.%09u\n", abs(val), -val2);
else
return sprintf(buf, "%d.%09u\n", val, val2);
case IIO_VAL_FRACTIONAL:
@@ -912,6 +912,53 @@ void iio_device_free(struct iio_dev *dev)
}
EXPORT_SYMBOL(iio_device_free);
+static void devm_iio_device_release(struct device *dev, void *res)
+{
+ iio_device_free(*(struct iio_dev **)res);
+}
+
+static int devm_iio_device_match(struct device *dev, void *res, void *data)
+{
+ struct iio_dev **r = res;
+ if (!r || !*r) {
+ WARN_ON(!r || !*r);
+ return 0;
+ }
+ return *r == data;
+}
+
+struct iio_dev *devm_iio_device_alloc(struct device *dev, int sizeof_priv)
+{
+ struct iio_dev **ptr, *iio_dev;
+
+ ptr = devres_alloc(devm_iio_device_release, sizeof(*ptr),
+ GFP_KERNEL);
+ if (!ptr)
+ return NULL;
+
+ /* use raw alloc_dr for kmalloc caller tracing */
+ iio_dev = iio_device_alloc(sizeof_priv);
+ if (iio_dev) {
+ *ptr = iio_dev;
+ devres_add(dev, ptr);
+ } else {
+ devres_free(ptr);
+ }
+
+ return iio_dev;
+}
+EXPORT_SYMBOL_GPL(devm_iio_device_alloc);
+
+void devm_iio_device_free(struct device *dev, struct iio_dev *iio_dev)
+{
+ int rc;
+
+ rc = devres_release(dev, devm_iio_device_release,
+ devm_iio_device_match, iio_dev);
+ WARN_ON(rc);
+}
+EXPORT_SYMBOL_GPL(devm_iio_device_free);
+
/**
* iio_chrdev_open() - chrdev file open for buffer access and ioctls
**/
diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
index 5ef1a396e0c9..bf9fa0d7aff9 100644
--- a/drivers/iio/light/Kconfig
+++ b/drivers/iio/light/Kconfig
@@ -1,6 +1,8 @@
#
# Light sensors
#
+# When adding new entries keep the list in alphabetical order
+
menu "Light sensors"
config ADJD_S311
@@ -15,6 +17,27 @@ config ADJD_S311
This driver can also be built as a module. If so, the module
will be called adjd_s311.
+config APDS9300
+ tristate "APDS9300 ambient light sensor"
+ depends on I2C
+ help
+ Say Y here if you want to build a driver for the Avago APDS9300
+ ambient light sensor.
+
+ To compile this driver as a module, choose M here: the
+ module will be called apds9300.
+
+config HID_SENSOR_ALS
+ depends on HID_SENSOR_HUB
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ select HID_SENSOR_IIO_COMMON
+ select HID_SENSOR_IIO_TRIGGER
+ tristate "HID ALS"
+ help
+ Say yes here to build support for the HID SENSOR
+ Ambient light sensor.
+
config SENSORS_LM3533
tristate "LM3533 ambient light sensor"
depends on MFD_LM3533
@@ -52,15 +75,4 @@ config VCNL4000
To compile this driver as a module, choose M here: the
module will be called vcnl4000.
-config HID_SENSOR_ALS
- depends on HID_SENSOR_HUB
- select IIO_BUFFER
- select IIO_TRIGGERED_BUFFER
- select HID_SENSOR_IIO_COMMON
- select HID_SENSOR_IIO_TRIGGER
- tristate "HID ALS"
- help
- Say yes here to build support for the HID SENSOR
- Ambient light sensor.
-
endmenu
diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile
index 040d9c75f8e6..354ee9ab2379 100644
--- a/drivers/iio/light/Makefile
+++ b/drivers/iio/light/Makefile
@@ -2,8 +2,10 @@
# Makefile for IIO Light sensors
#
+# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_ADJD_S311) += adjd_s311.o
+obj-$(CONFIG_APDS9300) += apds9300.o
+obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o
obj-$(CONFIG_SENSORS_LM3533) += lm3533-als.o
obj-$(CONFIG_SENSORS_TSL2563) += tsl2563.o
obj-$(CONFIG_VCNL4000) += vcnl4000.o
-obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o
diff --git a/drivers/iio/light/adjd_s311.c b/drivers/iio/light/adjd_s311.c
index 5f4749e60b04..55b9e185d164 100644
--- a/drivers/iio/light/adjd_s311.c
+++ b/drivers/iio/light/adjd_s311.c
@@ -293,11 +293,10 @@ static int adjd_s311_probe(struct i2c_client *client,
struct iio_dev *indio_dev;
int err;
- indio_dev = iio_device_alloc(sizeof(*data));
- if (indio_dev == NULL) {
- err = -ENOMEM;
- goto exit;
- }
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (indio_dev == NULL)
+ return -ENOMEM;
+
data = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev);
data->client = client;
@@ -312,7 +311,7 @@ static int adjd_s311_probe(struct i2c_client *client,
err = iio_triggered_buffer_setup(indio_dev, NULL,
adjd_s311_trigger_handler, NULL);
if (err < 0)
- goto exit_free_device;
+ return err;
err = iio_device_register(indio_dev);
if (err)
@@ -324,9 +323,6 @@ static int adjd_s311_probe(struct i2c_client *client,
exit_unreg_buffer:
iio_triggered_buffer_cleanup(indio_dev);
-exit_free_device:
- iio_device_free(indio_dev);
-exit:
return err;
}
@@ -338,7 +334,6 @@ static int adjd_s311_remove(struct i2c_client *client)
iio_device_unregister(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
kfree(data->buffer);
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/iio/light/apds9300.c b/drivers/iio/light/apds9300.c
new file mode 100644
index 000000000000..66a58bda6dc8
--- /dev/null
+++ b/drivers/iio/light/apds9300.c
@@ -0,0 +1,512 @@
+/*
+ * apds9300.c - IIO driver for Avago APDS9300 ambient light sensor
+ *
+ * Copyright 2013 Oleksandr Kravchenko <o.v.kravchenko@globallogic.com>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License. See the file COPYING in the main
+ * directory of this archive for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/interrupt.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/events.h>
+
+#define APDS9300_DRV_NAME "apds9300"
+#define APDS9300_IRQ_NAME "apds9300_event"
+
+/* Command register bits */
+#define APDS9300_CMD BIT(7) /* Select command register. Must write as 1 */
+#define APDS9300_WORD BIT(5) /* I2C write/read: if 1 word, if 0 byte */
+#define APDS9300_CLEAR BIT(6) /* Interrupt clear. Clears pending interrupt */
+
+/* Register set */
+#define APDS9300_CONTROL 0x00 /* Control of basic functions */
+#define APDS9300_THRESHLOWLOW 0x02 /* Low byte of low interrupt threshold */
+#define APDS9300_THRESHHIGHLOW 0x04 /* Low byte of high interrupt threshold */
+#define APDS9300_INTERRUPT 0x06 /* Interrupt control */
+#define APDS9300_DATA0LOW 0x0c /* Low byte of ADC channel 0 */
+#define APDS9300_DATA1LOW 0x0e /* Low byte of ADC channel 1 */
+
+/* Power on/off value for APDS9300_CONTROL register */
+#define APDS9300_POWER_ON 0x03
+#define APDS9300_POWER_OFF 0x00
+
+/* Interrupts */
+#define APDS9300_INTR_ENABLE 0x10
+/* Interrupt Persist Function: Any value outside of threshold range */
+#define APDS9300_THRESH_INTR 0x01
+
+#define APDS9300_THRESH_MAX 0xffff /* Max threshold value */
+
+struct apds9300_data {
+ struct i2c_client *client;
+ struct mutex mutex;
+ int power_state;
+ int thresh_low;
+ int thresh_hi;
+ int intr_en;
+};
+
+/* Lux calculation */
+
+/* Calculated values 1000 * (CH1/CH0)^1.4 for CH1/CH0 from 0 to 0.52 */
+static const u16 apds9300_lux_ratio[] = {
+ 0, 2, 4, 7, 11, 15, 19, 24, 29, 34, 40, 45, 51, 57, 64, 70, 77, 84, 91,
+ 98, 105, 112, 120, 128, 136, 144, 152, 160, 168, 177, 185, 194, 203,
+ 212, 221, 230, 239, 249, 258, 268, 277, 287, 297, 307, 317, 327, 337,
+ 347, 358, 368, 379, 390, 400,
+};
+
+static unsigned long apds9300_calculate_lux(u16 ch0, u16 ch1)
+{
+ unsigned long lux, tmp;
+
+ /* avoid division by zero */
+ if (ch0 == 0)
+ return 0;
+
+ tmp = DIV_ROUND_UP(ch1 * 100, ch0);
+ if (tmp <= 52) {
+ lux = 3150 * ch0 - (unsigned long)DIV_ROUND_UP_ULL(ch0
+ * apds9300_lux_ratio[tmp] * 5930ull, 1000);
+ } else if (tmp <= 65) {
+ lux = 2290 * ch0 - 2910 * ch1;
+ } else if (tmp <= 80) {
+ lux = 1570 * ch0 - 1800 * ch1;
+ } else if (tmp <= 130) {
+ lux = 338 * ch0 - 260 * ch1;
+ } else {
+ lux = 0;
+ }
+
+ return lux / 100000;
+}
+
+static int apds9300_get_adc_val(struct apds9300_data *data, int adc_number)
+{
+ int ret;
+ u8 flags = APDS9300_CMD | APDS9300_WORD;
+
+ if (!data->power_state)
+ return -EBUSY;
+
+ /* Select ADC0 or ADC1 data register */
+ flags |= adc_number ? APDS9300_DATA1LOW : APDS9300_DATA0LOW;
+
+ ret = i2c_smbus_read_word_data(data->client, flags);
+ if (ret < 0)
+ dev_err(&data->client->dev,
+ "failed to read ADC%d value\n", adc_number);
+
+ return ret;
+}
+
+static int apds9300_set_thresh_low(struct apds9300_data *data, int value)
+{
+ int ret;
+
+ if (!data->power_state)
+ return -EBUSY;
+
+ if (value > APDS9300_THRESH_MAX)
+ return -EINVAL;
+
+ ret = i2c_smbus_write_word_data(data->client, APDS9300_THRESHLOWLOW
+ | APDS9300_CMD | APDS9300_WORD, value);
+ if (ret) {
+ dev_err(&data->client->dev, "failed to set thresh_low\n");
+ return ret;
+ }
+ data->thresh_low = value;
+
+ return 0;
+}
+
+static int apds9300_set_thresh_hi(struct apds9300_data *data, int value)
+{
+ int ret;
+
+ if (!data->power_state)
+ return -EBUSY;
+
+ if (value > APDS9300_THRESH_MAX)
+ return -EINVAL;
+
+ ret = i2c_smbus_write_word_data(data->client, APDS9300_THRESHHIGHLOW
+ | APDS9300_CMD | APDS9300_WORD, value);
+ if (ret) {
+ dev_err(&data->client->dev, "failed to set thresh_hi\n");
+ return ret;
+ }
+ data->thresh_hi = value;
+
+ return 0;
+}
+
+static int apds9300_set_intr_state(struct apds9300_data *data, int state)
+{
+ int ret;
+ u8 cmd;
+
+ if (!data->power_state)
+ return -EBUSY;
+
+ cmd = state ? APDS9300_INTR_ENABLE | APDS9300_THRESH_INTR : 0x00;
+ ret = i2c_smbus_write_byte_data(data->client,
+ APDS9300_INTERRUPT | APDS9300_CMD, cmd);
+ if (ret) {
+ dev_err(&data->client->dev,
+ "failed to set interrupt state %d\n", state);
+ return ret;
+ }
+ data->intr_en = state;
+
+ return 0;
+}
+
+static int apds9300_set_power_state(struct apds9300_data *data, int state)
+{
+ int ret;
+ u8 cmd;
+
+ cmd = state ? APDS9300_POWER_ON : APDS9300_POWER_OFF;
+ ret = i2c_smbus_write_byte_data(data->client,
+ APDS9300_CONTROL | APDS9300_CMD, cmd);
+ if (ret) {
+ dev_err(&data->client->dev,
+ "failed to set power state %d\n", state);
+ return ret;
+ }
+ data->power_state = state;
+
+ return 0;
+}
+
+static void apds9300_clear_intr(struct apds9300_data *data)
+{
+ int ret;
+
+ ret = i2c_smbus_write_byte(data->client, APDS9300_CLEAR | APDS9300_CMD);
+ if (ret < 0)
+ dev_err(&data->client->dev, "failed to clear interrupt\n");
+}
+
+static int apds9300_chip_init(struct apds9300_data *data)
+{
+ int ret;
+
+ /* Need to set power off to ensure that the chip is off */
+ ret = apds9300_set_power_state(data, 0);
+ if (ret < 0)
+ goto err;
+ /*
+ * Probe the chip. To do so we try to power up the device and then to
+ * read back the 0x03 code
+ */
+ ret = apds9300_set_power_state(data, 1);
+ if (ret < 0)
+ goto err;
+ ret = i2c_smbus_read_byte_data(data->client,
+ APDS9300_CONTROL | APDS9300_CMD);
+ if (ret != APDS9300_POWER_ON) {
+ ret = -ENODEV;
+ goto err;
+ }
+ /*
+ * Disable interrupt to ensure thai it is doesn't enable
+ * i.e. after device soft reset
+ */
+ ret = apds9300_set_intr_state(data, 0);
+ if (ret < 0)
+ goto err;
+
+ return 0;
+
+err:
+ dev_err(&data->client->dev, "failed to init the chip\n");
+ return ret;
+}
+
+static int apds9300_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, int *val, int *val2,
+ long mask)
+{
+ int ch0, ch1, ret = -EINVAL;
+ struct apds9300_data *data = iio_priv(indio_dev);
+
+ mutex_lock(&data->mutex);
+ switch (chan->type) {
+ case IIO_LIGHT:
+ ch0 = apds9300_get_adc_val(data, 0);
+ if (ch0 < 0) {
+ ret = ch0;
+ break;
+ }
+ ch1 = apds9300_get_adc_val(data, 1);
+ if (ch1 < 0) {
+ ret = ch1;
+ break;
+ }
+ *val = apds9300_calculate_lux(ch0, ch1);
+ ret = IIO_VAL_INT;
+ break;
+ case IIO_INTENSITY:
+ ret = apds9300_get_adc_val(data, chan->channel);
+ if (ret < 0)
+ break;
+ *val = ret;
+ ret = IIO_VAL_INT;
+ break;
+ default:
+ break;
+ }
+ mutex_unlock(&data->mutex);
+
+ return ret;
+}
+
+static int apds9300_read_thresh(struct iio_dev *indio_dev, u64 event_code,
+ int *val)
+{
+ struct apds9300_data *data = iio_priv(indio_dev);
+
+ switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
+ case IIO_EV_DIR_RISING:
+ *val = data->thresh_hi;
+ break;
+ case IIO_EV_DIR_FALLING:
+ *val = data->thresh_low;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int apds9300_write_thresh(struct iio_dev *indio_dev, u64 event_code,
+ int val)
+{
+ struct apds9300_data *data = iio_priv(indio_dev);
+ int ret;
+
+ mutex_lock(&data->mutex);
+ if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_RISING)
+ ret = apds9300_set_thresh_hi(data, val);
+ else
+ ret = apds9300_set_thresh_low(data, val);
+ mutex_unlock(&data->mutex);
+
+ return ret;
+}
+
+static int apds9300_read_interrupt_config(struct iio_dev *indio_dev,
+ u64 event_code)
+{
+ struct apds9300_data *data = iio_priv(indio_dev);
+
+ return data->intr_en;
+}
+
+static int apds9300_write_interrupt_config(struct iio_dev *indio_dev,
+ u64 event_code, int state)
+{
+ struct apds9300_data *data = iio_priv(indio_dev);
+ int ret;
+
+ mutex_lock(&data->mutex);
+ ret = apds9300_set_intr_state(data, state);
+ mutex_unlock(&data->mutex);
+
+ return ret;
+}
+
+static const struct iio_info apds9300_info_no_irq = {
+ .driver_module = THIS_MODULE,
+ .read_raw = apds9300_read_raw,
+};
+
+static const struct iio_info apds9300_info = {
+ .driver_module = THIS_MODULE,
+ .read_raw = apds9300_read_raw,
+ .read_event_value = apds9300_read_thresh,
+ .write_event_value = apds9300_write_thresh,
+ .read_event_config = apds9300_read_interrupt_config,
+ .write_event_config = apds9300_write_interrupt_config,
+};
+
+static const struct iio_chan_spec apds9300_channels[] = {
+ {
+ .type = IIO_LIGHT,
+ .channel = 0,
+ .indexed = true,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
+ }, {
+ .type = IIO_INTENSITY,
+ .channel = 0,
+ .channel2 = IIO_MOD_LIGHT_BOTH,
+ .indexed = true,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .event_mask = (IIO_EV_BIT(IIO_EV_TYPE_THRESH,
+ IIO_EV_DIR_RISING) |
+ IIO_EV_BIT(IIO_EV_TYPE_THRESH,
+ IIO_EV_DIR_FALLING)),
+ }, {
+ .type = IIO_INTENSITY,
+ .channel = 1,
+ .channel2 = IIO_MOD_LIGHT_IR,
+ .indexed = true,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ },
+};
+
+static irqreturn_t apds9300_interrupt_handler(int irq, void *private)
+{
+ struct iio_dev *dev_info = private;
+ struct apds9300_data *data = iio_priv(dev_info);
+
+ iio_push_event(dev_info,
+ IIO_UNMOD_EVENT_CODE(IIO_INTENSITY, 0,
+ IIO_EV_TYPE_THRESH,
+ IIO_EV_DIR_EITHER),
+ iio_get_time_ns());
+
+ apds9300_clear_intr(data);
+
+ return IRQ_HANDLED;
+}
+
+static int apds9300_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct apds9300_data *data;
+ struct iio_dev *indio_dev;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ data = iio_priv(indio_dev);
+ i2c_set_clientdata(client, indio_dev);
+ data->client = client;
+
+ ret = apds9300_chip_init(data);
+ if (ret < 0)
+ goto err;
+
+ mutex_init(&data->mutex);
+
+ indio_dev->dev.parent = &client->dev;
+ indio_dev->channels = apds9300_channels;
+ indio_dev->num_channels = ARRAY_SIZE(apds9300_channels);
+ indio_dev->name = APDS9300_DRV_NAME;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+
+ if (client->irq)
+ indio_dev->info = &apds9300_info;
+ else
+ indio_dev->info = &apds9300_info_no_irq;
+
+ if (client->irq) {
+ ret = devm_request_threaded_irq(&client->dev, client->irq,
+ NULL, apds9300_interrupt_handler,
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ APDS9300_IRQ_NAME, indio_dev);
+ if (ret) {
+ dev_err(&client->dev, "irq request error %d\n", -ret);
+ goto err;
+ }
+ }
+
+ ret = iio_device_register(indio_dev);
+ if (ret < 0)
+ goto err;
+
+ return 0;
+
+err:
+ /* Ensure that power off in case of error */
+ apds9300_set_power_state(data, 0);
+ return ret;
+}
+
+static int apds9300_remove(struct i2c_client *client)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct apds9300_data *data = iio_priv(indio_dev);
+
+ iio_device_unregister(indio_dev);
+
+ /* Ensure that power off and interrupts are disabled */
+ apds9300_set_intr_state(data, 0);
+ apds9300_set_power_state(data, 0);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int apds9300_suspend(struct device *dev)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+ struct apds9300_data *data = iio_priv(indio_dev);
+ int ret;
+
+ mutex_lock(&data->mutex);
+ ret = apds9300_set_power_state(data, 0);
+ mutex_unlock(&data->mutex);
+
+ return ret;
+}
+
+static int apds9300_resume(struct device *dev)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+ struct apds9300_data *data = iio_priv(indio_dev);
+ int ret;
+
+ mutex_lock(&data->mutex);
+ ret = apds9300_set_power_state(data, 1);
+ mutex_unlock(&data->mutex);
+
+ return ret;
+}
+
+static SIMPLE_DEV_PM_OPS(apds9300_pm_ops, apds9300_suspend, apds9300_resume);
+#define APDS9300_PM_OPS (&apds9300_pm_ops)
+#else
+#define APDS9300_PM_OPS NULL
+#endif
+
+static struct i2c_device_id apds9300_id[] = {
+ { APDS9300_DRV_NAME, 0 },
+ { }
+};
+
+MODULE_DEVICE_TABLE(i2c, apds9300_id);
+
+static struct i2c_driver apds9300_driver = {
+ .driver = {
+ .name = APDS9300_DRV_NAME,
+ .owner = THIS_MODULE,
+ .pm = APDS9300_PM_OPS,
+ },
+ .probe = apds9300_probe,
+ .remove = apds9300_remove,
+ .id_table = apds9300_id,
+};
+
+module_i2c_driver(apds9300_driver);
+
+MODULE_AUTHOR("Kravchenko Oleksandr <o.v.kravchenko@globallogic.com>");
+MODULE_AUTHOR("GlobalLogic inc.");
+MODULE_DESCRIPTION("APDS9300 ambient light photo sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c
index cdc2cad0f01b..84cf0043c99d 100644
--- a/drivers/iio/light/hid-sensor-als.c
+++ b/drivers/iio/light/hid-sensor-als.c
@@ -30,10 +30,6 @@
#include <linux/iio/triggered_buffer.h>
#include "../common/hid-sensors/hid-sensor-trigger.h"
-/*Format: HID-SENSOR-usage_id_in_hex*/
-/*Usage ID from spec for Ambiant-Light: 0x200041*/
-#define DRIVER_NAME "HID-SENSOR-200041"
-
#define CHANNEL_SCAN_INDEX_ILLUM 0
struct als_state {
@@ -253,11 +249,9 @@ static int hid_als_probe(struct platform_device *pdev)
struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
struct iio_chan_spec *channels;
- indio_dev = iio_device_alloc(sizeof(struct als_state));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct als_state));
+ if (!indio_dev)
+ return -ENOMEM;
platform_set_drvdata(pdev, indio_dev);
als_state = iio_priv(indio_dev);
@@ -268,14 +262,13 @@ static int hid_als_probe(struct platform_device *pdev)
&als_state->common_attributes);
if (ret) {
dev_err(&pdev->dev, "failed to setup common attributes\n");
- goto error_free_dev;
+ return ret;
}
channels = kmemdup(als_channels, sizeof(als_channels), GFP_KERNEL);
if (!channels) {
- ret = -ENOMEM;
dev_err(&pdev->dev, "failed to duplicate channels\n");
- goto error_free_dev;
+ return -ENOMEM;
}
ret = als_parse_report(pdev, hsdev, channels,
@@ -333,9 +326,6 @@ error_unreg_buffer_funcs:
iio_triggered_buffer_cleanup(indio_dev);
error_free_dev_mem:
kfree(indio_dev->channels);
-error_free_dev:
- iio_device_free(indio_dev);
-error_ret:
return ret;
}
@@ -350,14 +340,23 @@ static int hid_als_remove(struct platform_device *pdev)
hid_sensor_remove_trigger(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
kfree(indio_dev->channels);
- iio_device_free(indio_dev);
return 0;
}
+static struct platform_device_id hid_als_ids[] = {
+ {
+ /* Format: HID-SENSOR-usage_id_in_hex_lowercase */
+ .name = "HID-SENSOR-200041",
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, hid_als_ids);
+
static struct platform_driver hid_als_platform_driver = {
+ .id_table = hid_als_ids,
.driver = {
- .name = DRIVER_NAME,
+ .name = KBUILD_MODNAME,
.owner = THIS_MODULE,
},
.probe = hid_als_probe,
diff --git a/drivers/iio/light/lm3533-als.c b/drivers/iio/light/lm3533-als.c
index 5fa31a4ef82a..c1aadc6b865a 100644
--- a/drivers/iio/light/lm3533-als.c
+++ b/drivers/iio/light/lm3533-als.c
@@ -847,7 +847,7 @@ static int lm3533_als_probe(struct platform_device *pdev)
return -EINVAL;
}
- indio_dev = iio_device_alloc(sizeof(*als));
+ indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*als));
if (!indio_dev)
return -ENOMEM;
@@ -870,7 +870,7 @@ static int lm3533_als_probe(struct platform_device *pdev)
if (als->irq) {
ret = lm3533_als_setup_irq(als, indio_dev);
if (ret)
- goto err_free_dev;
+ return ret;
}
ret = lm3533_als_setup(als, pdata);
@@ -894,8 +894,6 @@ err_disable:
err_free_irq:
if (als->irq)
free_irq(als->irq, indio_dev);
-err_free_dev:
- iio_device_free(indio_dev);
return ret;
}
@@ -910,7 +908,6 @@ static int lm3533_als_remove(struct platform_device *pdev)
lm3533_als_disable(als);
if (als->irq)
free_irq(als->irq, indio_dev);
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/iio/light/tsl2563.c b/drivers/iio/light/tsl2563.c
index 1f529f36f138..ebb962c5c323 100644
--- a/drivers/iio/light/tsl2563.c
+++ b/drivers/iio/light/tsl2563.c
@@ -702,7 +702,7 @@ static int tsl2563_probe(struct i2c_client *client,
int err = 0;
u8 id = 0;
- indio_dev = iio_device_alloc(sizeof(*chip));
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
if (!indio_dev)
return -ENOMEM;
@@ -714,13 +714,13 @@ static int tsl2563_probe(struct i2c_client *client,
err = tsl2563_detect(chip);
if (err) {
dev_err(&client->dev, "detect error %d\n", -err);
- goto fail1;
+ return err;
}
err = tsl2563_read_id(chip, &id);
if (err) {
dev_err(&client->dev, "read id error %d\n", -err);
- goto fail1;
+ return err;
}
mutex_init(&chip->lock);
@@ -751,7 +751,7 @@ static int tsl2563_probe(struct i2c_client *client,
indio_dev->info = &tsl2563_info_no_irq;
if (client->irq) {
- err = request_threaded_irq(client->irq,
+ err = devm_request_threaded_irq(&client->dev, client->irq,
NULL,
&tsl2563_event_handler,
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
@@ -759,14 +759,14 @@ static int tsl2563_probe(struct i2c_client *client,
indio_dev);
if (err) {
dev_err(&client->dev, "irq request error %d\n", -err);
- goto fail1;
+ return err;
}
}
err = tsl2563_configure(chip);
if (err) {
dev_err(&client->dev, "configure error %d\n", -err);
- goto fail2;
+ return err;
}
INIT_DELAYED_WORK(&chip->poweroff_work, tsl2563_poweroff_work);
@@ -777,19 +777,14 @@ static int tsl2563_probe(struct i2c_client *client,
err = iio_device_register(indio_dev);
if (err) {
dev_err(&client->dev, "iio registration error %d\n", -err);
- goto fail3;
+ goto fail;
}
return 0;
-fail3:
+fail:
cancel_delayed_work(&chip->poweroff_work);
flush_scheduled_work();
-fail2:
- if (client->irq)
- free_irq(client->irq, indio_dev);
-fail1:
- iio_device_free(indio_dev);
return err;
}
@@ -807,10 +802,6 @@ static int tsl2563_remove(struct i2c_client *client)
chip->intr);
flush_scheduled_work();
tsl2563_set_power(chip, 0);
- if (client->irq)
- free_irq(client->irq, indio_dev);
-
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c
index 1014943d949a..2bb304215b1d 100644
--- a/drivers/iio/light/vcnl4000.c
+++ b/drivers/iio/light/vcnl4000.c
@@ -157,7 +157,7 @@ static int vcnl4000_probe(struct i2c_client *client,
struct iio_dev *indio_dev;
int ret;
- indio_dev = iio_device_alloc(sizeof(*data));
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
@@ -167,7 +167,7 @@ static int vcnl4000_probe(struct i2c_client *client,
ret = i2c_smbus_read_byte_data(data->client, VCNL4000_PROD_REV);
if (ret < 0)
- goto error_free_dev;
+ return ret;
dev_info(&client->dev, "VCNL4000 Ambient light/proximity sensor, Prod %02x, Rev: %02x\n",
ret >> 4, ret & 0xf);
@@ -181,22 +181,14 @@ static int vcnl4000_probe(struct i2c_client *client,
ret = iio_device_register(indio_dev);
if (ret < 0)
- goto error_free_dev;
+ return ret;
return 0;
-
-error_free_dev:
- iio_device_free(indio_dev);
- return ret;
}
static int vcnl4000_remove(struct i2c_client *client)
{
- struct iio_dev *indio_dev = i2c_get_clientdata(client);
-
- iio_device_unregister(indio_dev);
- iio_device_free(indio_dev);
-
+ iio_device_unregister(i2c_get_clientdata(client));
return 0;
}
diff --git a/drivers/iio/magnetometer/Kconfig b/drivers/iio/magnetometer/Kconfig
index c332b0ae4a3b..4fa923f37b97 100644
--- a/drivers/iio/magnetometer/Kconfig
+++ b/drivers/iio/magnetometer/Kconfig
@@ -1,6 +1,8 @@
#
# Magnetometer sensors
#
+# When adding new entries keep the list in alphabetical order
+
menu "Magnetometer sensors"
config AK8975
@@ -36,8 +38,8 @@ config IIO_ST_MAGN_3AXIS
Say yes here to build support for STMicroelectronics magnetometers:
LSM303DLHC, LSM303DLM, LIS3MDL.
- This driver can also be built as a module. If so, will be created
- these modules:
+ This driver can also be built as a module. If so, these modules
+ will be created:
- st_magn (core functions for the driver [it is mandatory]);
- st_magn_i2c (necessary for the I2C devices [optional*]);
- st_magn_spi (necessary for the SPI devices [optional*]);
diff --git a/drivers/iio/magnetometer/Makefile b/drivers/iio/magnetometer/Makefile
index 7f328e37fbab..f91b1b68d392 100644
--- a/drivers/iio/magnetometer/Makefile
+++ b/drivers/iio/magnetometer/Makefile
@@ -2,6 +2,7 @@
# Makefile for industrial I/O Magnetometer sensor drivers
#
+# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_AK8975) += ak8975.o
obj-$(CONFIG_HID_SENSOR_MAGNETOMETER_3D) += hid-sensor-magn-3d.o
diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index 99f4e494513b..5a6162d1a2c0 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -30,10 +30,6 @@
#include <linux/iio/triggered_buffer.h>
#include "../common/hid-sensors/hid-sensor-trigger.h"
-/*Format: HID-SENSOR-usage_id_in_hex*/
-/*Usage ID from spec for Magnetometer-3D: 0x200083*/
-#define DRIVER_NAME "HID-SENSOR-200083"
-
enum magn_3d_channel {
CHANNEL_SCAN_INDEX_X,
CHANNEL_SCAN_INDEX_Y,
@@ -287,11 +283,11 @@ static int hid_magn_3d_probe(struct platform_device *pdev)
struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
struct iio_chan_spec *channels;
- indio_dev = iio_device_alloc(sizeof(struct magn_3d_state));
- if (indio_dev == NULL) {
- ret = -ENOMEM;
- goto error_ret;
- }
+ indio_dev = devm_iio_device_alloc(&pdev->dev,
+ sizeof(struct magn_3d_state));
+ if (indio_dev == NULL)
+ return -ENOMEM;
+
platform_set_drvdata(pdev, indio_dev);
magn_state = iio_priv(indio_dev);
@@ -303,15 +299,14 @@ static int hid_magn_3d_probe(struct platform_device *pdev)
&magn_state->common_attributes);
if (ret) {
dev_err(&pdev->dev, "failed to setup common attributes\n");
- goto error_free_dev;
+ return ret;
}
channels = kmemdup(magn_3d_channels, sizeof(magn_3d_channels),
GFP_KERNEL);
if (!channels) {
- ret = -ENOMEM;
dev_err(&pdev->dev, "failed to duplicate channels\n");
- goto error_free_dev;
+ return -ENOMEM;
}
ret = magn_3d_parse_report(pdev, hsdev, channels,
@@ -368,9 +363,6 @@ error_unreg_buffer_funcs:
iio_triggered_buffer_cleanup(indio_dev);
error_free_dev_mem:
kfree(indio_dev->channels);
-error_free_dev:
- iio_device_free(indio_dev);
-error_ret:
return ret;
}
@@ -385,14 +377,23 @@ static int hid_magn_3d_remove(struct platform_device *pdev)
hid_sensor_remove_trigger(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
kfree(indio_dev->channels);
- iio_device_free(indio_dev);
return 0;
}
+static struct platform_device_id hid_magn_3d_ids[] = {
+ {
+ /* Format: HID-SENSOR-usage_id_in_hex_lowercase */
+ .name = "HID-SENSOR-200083",
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, hid_magn_3d_ids);
+
static struct platform_driver hid_magn_3d_platform_driver = {
+ .id_table = hid_magn_3d_ids,
.driver = {
- .name = DRIVER_NAME,
+ .name = KBUILD_MODNAME,
.owner = THIS_MODULE,
},
.probe = hid_magn_3d_probe,
diff --git a/drivers/iio/magnetometer/st_magn.h b/drivers/iio/magnetometer/st_magn.h
index 7e81d00ef0c3..694e33e0fb72 100644
--- a/drivers/iio/magnetometer/st_magn.h
+++ b/drivers/iio/magnetometer/st_magn.h
@@ -18,7 +18,8 @@
#define LSM303DLM_MAGN_DEV_NAME "lsm303dlm_magn"
#define LIS3MDL_MAGN_DEV_NAME "lis3mdl"
-int st_magn_common_probe(struct iio_dev *indio_dev);
+int st_magn_common_probe(struct iio_dev *indio_dev,
+ struct st_sensors_platform_data *pdata);
void st_magn_common_remove(struct iio_dev *indio_dev);
#ifdef CONFIG_IIO_BUFFER
diff --git a/drivers/iio/magnetometer/st_magn_core.c b/drivers/iio/magnetometer/st_magn_core.c
index ebfe8f11a0c2..e8d2849cc81d 100644
--- a/drivers/iio/magnetometer/st_magn_core.c
+++ b/drivers/iio/magnetometer/st_magn_core.c
@@ -345,7 +345,8 @@ static const struct iio_info magn_info = {
.write_raw = &st_magn_write_raw,
};
-int st_magn_common_probe(struct iio_dev *indio_dev)
+int st_magn_common_probe(struct iio_dev *indio_dev,
+ struct st_sensors_platform_data *pdata)
{
int err;
struct st_sensor_data *mdata = iio_priv(indio_dev);
@@ -367,7 +368,7 @@ int st_magn_common_probe(struct iio_dev *indio_dev)
&mdata->sensor->fs.fs_avl[0];
mdata->odr = mdata->sensor->odr.odr_avl[0].hz;
- err = st_sensors_init_sensor(indio_dev);
+ err = st_sensors_init_sensor(indio_dev, pdata);
if (err < 0)
goto st_magn_common_probe_error;
@@ -406,7 +407,6 @@ void st_magn_common_remove(struct iio_dev *indio_dev)
st_sensors_deallocate_trigger(indio_dev);
st_magn_deallocate_ring(indio_dev);
}
- iio_device_free(indio_dev);
}
EXPORT_SYMBOL(st_magn_common_remove);
diff --git a/drivers/iio/magnetometer/st_magn_i2c.c b/drivers/iio/magnetometer/st_magn_i2c.c
index e6adc4a86425..892e0feeb5c1 100644
--- a/drivers/iio/magnetometer/st_magn_i2c.c
+++ b/drivers/iio/magnetometer/st_magn_i2c.c
@@ -25,27 +25,20 @@ static int st_magn_i2c_probe(struct i2c_client *client,
struct st_sensor_data *mdata;
int err;
- indio_dev = iio_device_alloc(sizeof(*mdata));
- if (indio_dev == NULL) {
- err = -ENOMEM;
- goto iio_device_alloc_error;
- }
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*mdata));
+ if (!indio_dev)
+ return -ENOMEM;
mdata = iio_priv(indio_dev);
mdata->dev = &client->dev;
st_sensors_i2c_configure(indio_dev, client, mdata);
- err = st_magn_common_probe(indio_dev);
+ err = st_magn_common_probe(indio_dev, NULL);
if (err < 0)
- goto st_magn_common_probe_error;
+ return err;
return 0;
-
-st_magn_common_probe_error:
- iio_device_free(indio_dev);
-iio_device_alloc_error:
- return err;
}
static int st_magn_i2c_remove(struct i2c_client *client)
diff --git a/drivers/iio/magnetometer/st_magn_spi.c b/drivers/iio/magnetometer/st_magn_spi.c
index 51adb797cb7d..a6143ea51dfc 100644
--- a/drivers/iio/magnetometer/st_magn_spi.c
+++ b/drivers/iio/magnetometer/st_magn_spi.c
@@ -24,27 +24,20 @@ static int st_magn_spi_probe(struct spi_device *spi)
struct st_sensor_data *mdata;
int err;
- indio_dev = iio_device_alloc(sizeof(*mdata));
- if (indio_dev == NULL) {
- err = -ENOMEM;
- goto iio_device_alloc_error;
- }
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*mdata));
+ if (!indio_dev)
+ return -ENOMEM;
mdata = iio_priv(indio_dev);
mdata->dev = &spi->dev;
st_sensors_spi_configure(indio_dev, spi, mdata);
- err = st_magn_common_probe(indio_dev);
+ err = st_magn_common_probe(indio_dev, NULL);
if (err < 0)
- goto st_magn_common_probe_error;
+ return err;
return 0;
-
-st_magn_common_probe_error:
- iio_device_free(indio_dev);
-iio_device_alloc_error:
- return err;
}
static int st_magn_spi_remove(struct spi_device *spi)
diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig
index 9427f01e1499..26fdc0bdb99d 100644
--- a/drivers/iio/pressure/Kconfig
+++ b/drivers/iio/pressure/Kconfig
@@ -1,21 +1,23 @@
#
# Pressure drivers
#
-menu "Pressure Sensors"
+# When adding new entries keep the list in alphabetical order
+
+menu "Pressure sensors"
config IIO_ST_PRESS
- tristate "STMicroelectronics pressures Driver"
+ tristate "STMicroelectronics pressure sensor Driver"
depends on (I2C || SPI_MASTER) && SYSFS
select IIO_ST_SENSORS_CORE
select IIO_ST_PRESS_I2C if (I2C)
select IIO_ST_PRESS_SPI if (SPI_MASTER)
select IIO_TRIGGERED_BUFFER if (IIO_BUFFER)
help
- Say yes here to build support for STMicroelectronics pressures:
- LPS331AP.
+ Say yes here to build support for STMicroelectronics pressure
+ sensors: LPS331AP.
- This driver can also be built as a module. If so, will be created
- these modules:
+ This driver can also be built as a module. If so, these modules
+ will be created:
- st_pressure (core functions for the driver [it is mandatory]);
- st_pressure_i2c (necessary for the I2C devices [optional*]);
- st_pressure_spi (necessary for the SPI devices [optional*]);
diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile
index d4bb33e5c846..be71464c2752 100644
--- a/drivers/iio/pressure/Makefile
+++ b/drivers/iio/pressure/Makefile
@@ -2,6 +2,7 @@
# Makefile for industrial I/O pressure drivers
#
+# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_IIO_ST_PRESS) += st_pressure.o
st_pressure-y := st_pressure_core.o
st_pressure-$(CONFIG_IIO_BUFFER) += st_pressure_buffer.o
diff --git a/drivers/iio/pressure/st_pressure.h b/drivers/iio/pressure/st_pressure.h
index 414e45ac9b9b..b0b630688da6 100644
--- a/drivers/iio/pressure/st_pressure.h
+++ b/drivers/iio/pressure/st_pressure.h
@@ -16,7 +16,16 @@
#define LPS331AP_PRESS_DEV_NAME "lps331ap"
-int st_press_common_probe(struct iio_dev *indio_dev);
+/**
+ * struct st_sensors_platform_data - default press platform data
+ * @drdy_int_pin: default press DRDY is available on INT1 pin.
+ */
+static const struct st_sensors_platform_data default_press_pdata = {
+ .drdy_int_pin = 1,
+};
+
+int st_press_common_probe(struct iio_dev *indio_dev,
+ struct st_sensors_platform_data *pdata);
void st_press_common_remove(struct iio_dev *indio_dev);
#ifdef CONFIG_IIO_BUFFER
diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c
index 3ffbc56917b4..ceebd3c27892 100644
--- a/drivers/iio/pressure/st_pressure_core.c
+++ b/drivers/iio/pressure/st_pressure_core.c
@@ -31,6 +31,9 @@
#define ST_PRESS_LSB_PER_MBAR 4096UL
#define ST_PRESS_KPASCAL_NANO_SCALE (100000000UL / \
ST_PRESS_LSB_PER_MBAR)
+#define ST_PRESS_LSB_PER_CELSIUS 480UL
+#define ST_PRESS_CELSIUS_NANO_SCALE (1000000000UL / \
+ ST_PRESS_LSB_PER_CELSIUS)
#define ST_PRESS_NUMBER_DATA_CHANNELS 1
/* DEFAULT VALUE FOR SENSORS */
@@ -53,12 +56,13 @@
#define ST_PRESS_1_FS_ADDR 0x23
#define ST_PRESS_1_FS_MASK 0x30
#define ST_PRESS_1_FS_AVL_1260_VAL 0x00
-#define ST_PRESS_1_FS_AVL_TEMP_GAIN 2083000
#define ST_PRESS_1_FS_AVL_1260_GAIN ST_PRESS_KPASCAL_NANO_SCALE
+#define ST_PRESS_1_FS_AVL_TEMP_GAIN ST_PRESS_CELSIUS_NANO_SCALE
#define ST_PRESS_1_BDU_ADDR 0x20
#define ST_PRESS_1_BDU_MASK 0x04
#define ST_PRESS_1_DRDY_IRQ_ADDR 0x22
-#define ST_PRESS_1_DRDY_IRQ_MASK 0x04
+#define ST_PRESS_1_DRDY_IRQ_INT1_MASK 0x04
+#define ST_PRESS_1_DRDY_IRQ_INT2_MASK 0x20
#define ST_PRESS_1_MULTIREAD_BIT true
#define ST_PRESS_1_TEMP_OFFSET 42500
@@ -116,7 +120,8 @@ static const struct st_sensors st_press_sensors[] = {
},
.drdy_irq = {
.addr = ST_PRESS_1_DRDY_IRQ_ADDR,
- .mask = ST_PRESS_1_DRDY_IRQ_MASK,
+ .mask_int1 = ST_PRESS_1_DRDY_IRQ_INT1_MASK,
+ .mask_int2 = ST_PRESS_1_DRDY_IRQ_INT2_MASK,
},
.multi_read_bit = ST_PRESS_1_MULTIREAD_BIT,
.bootime = 2,
@@ -202,7 +207,8 @@ static const struct iio_trigger_ops st_press_trigger_ops = {
#define ST_PRESS_TRIGGER_OPS NULL
#endif
-int st_press_common_probe(struct iio_dev *indio_dev)
+int st_press_common_probe(struct iio_dev *indio_dev,
+ struct st_sensors_platform_data *plat_data)
{
int err;
struct st_sensor_data *pdata = iio_priv(indio_dev);
@@ -224,7 +230,11 @@ int st_press_common_probe(struct iio_dev *indio_dev)
&pdata->sensor->fs.fs_avl[0];
pdata->odr = pdata->sensor->odr.odr_avl[0].hz;
- err = st_sensors_init_sensor(indio_dev);
+ if (!plat_data)
+ plat_data =
+ (struct st_sensors_platform_data *)&default_press_pdata;
+
+ err = st_sensors_init_sensor(indio_dev, plat_data);
if (err < 0)
goto st_press_common_probe_error;
@@ -265,7 +275,6 @@ void st_press_common_remove(struct iio_dev *indio_dev)
st_sensors_deallocate_trigger(indio_dev);
st_press_deallocate_ring(indio_dev);
}
- iio_device_free(indio_dev);
}
EXPORT_SYMBOL(st_press_common_remove);
diff --git a/drivers/iio/pressure/st_pressure_i2c.c b/drivers/iio/pressure/st_pressure_i2c.c
index 7cebcc73bfb0..08aac5e6251d 100644
--- a/drivers/iio/pressure/st_pressure_i2c.c
+++ b/drivers/iio/pressure/st_pressure_i2c.c
@@ -25,27 +25,20 @@ static int st_press_i2c_probe(struct i2c_client *client,
struct st_sensor_data *pdata;
int err;
- indio_dev = iio_device_alloc(sizeof(*pdata));
- if (indio_dev == NULL) {
- err = -ENOMEM;
- goto iio_device_alloc_error;
- }
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*pdata));
+ if (!indio_dev)
+ return -ENOMEM;
pdata = iio_priv(indio_dev);
pdata->dev = &client->dev;
st_sensors_i2c_configure(indio_dev, client, pdata);
- err = st_press_common_probe(indio_dev);
+ err = st_press_common_probe(indio_dev, client->dev.platform_data);
if (err < 0)
- goto st_press_common_probe_error;
+ return err;
return 0;
-
-st_press_common_probe_error:
- iio_device_free(indio_dev);
-iio_device_alloc_error:
- return err;
}
static int st_press_i2c_remove(struct i2c_client *client)
diff --git a/drivers/iio/pressure/st_pressure_spi.c b/drivers/iio/pressure/st_pressure_spi.c
index 17a14907940a..399a29b6017b 100644
--- a/drivers/iio/pressure/st_pressure_spi.c
+++ b/drivers/iio/pressure/st_pressure_spi.c
@@ -24,27 +24,20 @@ static int st_press_spi_probe(struct spi_device *spi)
struct st_sensor_data *pdata;
int err;
- indio_dev = iio_device_alloc(sizeof(*pdata));
- if (indio_dev == NULL) {
- err = -ENOMEM;
- goto iio_device_alloc_error;
- }
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*pdata));
+ if (indio_dev == NULL)
+ return -ENOMEM;
pdata = iio_priv(indio_dev);
pdata->dev = &spi->dev;
st_sensors_spi_configure(indio_dev, spi, pdata);
- err = st_press_common_probe(indio_dev);
+ err = st_press_common_probe(indio_dev, spi->dev.platform_data);
if (err < 0)
- goto st_press_common_probe_error;
+ return err;
return 0;
-
-st_press_common_probe_error:
- iio_device_free(indio_dev);
-iio_device_alloc_error:
- return err;
}
static int st_press_spi_remove(struct spi_device *spi)
diff --git a/drivers/iio/trigger/Kconfig b/drivers/iio/trigger/Kconfig
index 360fd508b088..79996123a71b 100644
--- a/drivers/iio/trigger/Kconfig
+++ b/drivers/iio/trigger/Kconfig
@@ -1,6 +1,8 @@
#
# Industrial I/O standalone triggers
#
+# When adding new entries keep the list in alphabetical order
+
menu "Triggers - standalone"
config IIO_INTERRUPT_TRIGGER
@@ -17,7 +19,7 @@ config IIO_SYSFS_TRIGGER
depends on SYSFS
select IRQ_WORK
help
- Provides support for using SYSFS entry as IIO triggers.
+ Provides support for using SYSFS entries as IIO triggers.
If unsure, say N (but it's safe to say "Y").
To compile this driver as a module, choose M here: the
diff --git a/drivers/iio/trigger/Makefile b/drivers/iio/trigger/Makefile
index ce319a51b6af..0694daecaf22 100644
--- a/drivers/iio/trigger/Makefile
+++ b/drivers/iio/trigger/Makefile
@@ -2,5 +2,6 @@
# Makefile for triggers not associated with iio-devices
#
+# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_IIO_INTERRUPT_TRIGGER) += iio-trig-interrupt.o
obj-$(CONFIG_IIO_SYSFS_TRIGGER) += iio-trig-sysfs.o
diff --git a/drivers/staging/iio/Documentation/device.txt b/drivers/staging/iio/Documentation/device.txt
index ea08d6213373..8be32e5a0af1 100644
--- a/drivers/staging/iio/Documentation/device.txt
+++ b/drivers/staging/iio/Documentation/device.txt
@@ -56,7 +56,7 @@ Then fill in the following:
- indio_dev->modes:
Specify whether direct access and / or ring buffer access is supported.
-- indio_dev->ring:
+- indio_dev->buffer:
An optional associated buffer.
- indio_dev->pollfunc:
Poll function related elements. This controls what occurs when a trigger
@@ -67,7 +67,7 @@ Then fill in the following:
- indio_dev->num_channels:
How many channels are there?
-Once these are set up, a call to iio_device_register(indio_dev),
+Once these are set up, a call to iio_device_register(indio_dev)
will register the device with the iio core.
Worth noting here is that, if a ring buffer is to be used, it can be
diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c
index 9f52a2857929..863f0861b729 100644
--- a/drivers/staging/iio/adc/mxs-lradc.c
+++ b/drivers/staging/iio/adc/mxs-lradc.c
@@ -841,14 +841,16 @@ static const struct iio_chan_spec mxs_lradc_chan_spec[] = {
MXS_ADC_CHAN(15, IIO_VOLTAGE), /* VDD5V */
};
-static void mxs_lradc_hw_init(struct mxs_lradc *lradc)
+static int mxs_lradc_hw_init(struct mxs_lradc *lradc)
{
/* The ADC always uses DELAY CHANNEL 0. */
const uint32_t adc_cfg =
(1 << (LRADC_DELAY_TRIGGER_DELAYS_OFFSET + 0)) |
(LRADC_DELAY_TIMER_PER << LRADC_DELAY_DELAY_OFFSET);
- stmp_reset_block(lradc->base);
+ int ret = stmp_reset_block(lradc->base);
+ if (ret)
+ return ret;
/* Configure DELAY CHANNEL 0 for generic ADC sampling. */
writel(adc_cfg, lradc->base + LRADC_DELAY(0));
@@ -869,6 +871,8 @@ static void mxs_lradc_hw_init(struct mxs_lradc *lradc)
/* Start internal temperature sensing. */
writel(0, lradc->base + LRADC_CTRL2);
+
+ return 0;
}
static void mxs_lradc_hw_stop(struct mxs_lradc *lradc)
@@ -905,7 +909,7 @@ static int mxs_lradc_probe(struct platform_device *pdev)
int i;
/* Allocate the IIO device. */
- iio = iio_device_alloc(sizeof(*lradc));
+ iio = devm_iio_device_alloc(dev, sizeof(*lradc));
if (!iio) {
dev_err(dev, "Failed to allocate IIO device\n");
return -ENOMEM;
@@ -917,10 +921,8 @@ static int mxs_lradc_probe(struct platform_device *pdev)
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
lradc->dev = &pdev->dev;
lradc->base = devm_ioremap_resource(dev, iores);
- if (IS_ERR(lradc->base)) {
- ret = PTR_ERR(lradc->base);
- goto err_addr;
- }
+ if (IS_ERR(lradc->base))
+ return PTR_ERR(lradc->base);
INIT_WORK(&lradc->ts_work, mxs_lradc_ts_work);
@@ -940,16 +942,14 @@ static int mxs_lradc_probe(struct platform_device *pdev)
/* Grab all IRQ sources */
for (i = 0; i < of_cfg->irq_count; i++) {
lradc->irq[i] = platform_get_irq(pdev, i);
- if (lradc->irq[i] < 0) {
- ret = -EINVAL;
- goto err_addr;
- }
+ if (lradc->irq[i] < 0)
+ return -EINVAL;
ret = devm_request_irq(dev, lradc->irq[i],
mxs_lradc_handle_irq, 0,
of_cfg->irq_name[i], iio);
if (ret)
- goto err_addr;
+ return ret;
}
platform_set_drvdata(pdev, iio);
@@ -969,14 +969,16 @@ static int mxs_lradc_probe(struct platform_device *pdev)
&mxs_lradc_trigger_handler,
&mxs_lradc_buffer_ops);
if (ret)
- goto err_addr;
+ return ret;
ret = mxs_lradc_trigger_init(iio);
if (ret)
goto err_trig;
/* Configure the hardware. */
- mxs_lradc_hw_init(lradc);
+ ret = mxs_lradc_hw_init(lradc);
+ if (ret)
+ goto err_dev;
/* Register the touchscreen input device. */
ret = mxs_lradc_ts_register(lradc);
@@ -998,8 +1000,6 @@ err_dev:
mxs_lradc_trigger_remove(iio);
err_trig:
iio_triggered_buffer_cleanup(iio);
-err_addr:
- iio_device_free(iio);
return ret;
}
@@ -1015,7 +1015,6 @@ static int mxs_lradc_remove(struct platform_device *pdev)
iio_device_unregister(iio);
iio_triggered_buffer_cleanup(iio);
mxs_lradc_trigger_remove(iio);
- iio_device_free(iio);
return 0;
}
diff --git a/drivers/staging/iio/adc/spear_adc.c b/drivers/staging/iio/adc/spear_adc.c
index 736219c30308..20f2d555e7cd 100644
--- a/drivers/staging/iio/adc/spear_adc.c
+++ b/drivers/staging/iio/adc/spear_adc.c
@@ -300,11 +300,10 @@ static int spear_adc_probe(struct platform_device *pdev)
int ret = -ENODEV;
int irq;
- iodev = iio_device_alloc(sizeof(struct spear_adc_info));
+ iodev = devm_iio_device_alloc(dev, sizeof(struct spear_adc_info));
if (!iodev) {
dev_err(dev, "failed allocating iio device\n");
- ret = -ENOMEM;
- goto errout1;
+ return -ENOMEM;
}
info = iio_priv(iodev);
@@ -318,8 +317,7 @@ static int spear_adc_probe(struct platform_device *pdev)
info->adc_base_spear6xx = of_iomap(np, 0);
if (!info->adc_base_spear6xx) {
dev_err(dev, "failed mapping memory\n");
- ret = -ENOMEM;
- goto errout2;
+ return -ENOMEM;
}
info->adc_base_spear3xx =
(struct adc_regs_spear3xx *)info->adc_base_spear6xx;
@@ -327,33 +325,33 @@ static int spear_adc_probe(struct platform_device *pdev)
info->clk = clk_get(dev, NULL);
if (IS_ERR(info->clk)) {
dev_err(dev, "failed getting clock\n");
- goto errout3;
+ goto errout1;
}
ret = clk_prepare_enable(info->clk);
if (ret) {
dev_err(dev, "failed enabling clock\n");
- goto errout4;
+ goto errout2;
}
irq = platform_get_irq(pdev, 0);
if ((irq < 0) || (irq >= NR_IRQS)) {
dev_err(dev, "failed getting interrupt resource\n");
ret = -EINVAL;
- goto errout5;
+ goto errout3;
}
ret = devm_request_irq(dev, irq, spear_adc_isr, 0, MOD_NAME, info);
if (ret < 0) {
dev_err(dev, "failed requesting interrupt\n");
- goto errout5;
+ goto errout3;
}
if (of_property_read_u32(np, "sampling-frequency",
&info->sampling_freq)) {
dev_err(dev, "sampling-frequency missing in DT\n");
ret = -EINVAL;
- goto errout5;
+ goto errout3;
}
/*
@@ -383,21 +381,18 @@ static int spear_adc_probe(struct platform_device *pdev)
ret = iio_device_register(iodev);
if (ret)
- goto errout5;
+ goto errout3;
dev_info(dev, "SPEAR ADC driver loaded, IRQ %d\n", irq);
return 0;
-errout5:
- clk_disable_unprepare(info->clk);
-errout4:
- clk_put(info->clk);
errout3:
- iounmap(info->adc_base_spear6xx);
+ clk_disable_unprepare(info->clk);
errout2:
- iio_device_free(iodev);
+ clk_put(info->clk);
errout1:
+ iounmap(info->adc_base_spear6xx);
return ret;
}
@@ -410,7 +405,6 @@ static int spear_adc_remove(struct platform_device *pdev)
clk_disable_unprepare(info->clk);
clk_put(info->clk);
iounmap(info->adc_base_spear6xx);
- iio_device_free(iodev);
return 0;
}
diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c
index 506b5a7d96c8..1e1356825d6d 100644
--- a/drivers/staging/iio/addac/adt7316.c
+++ b/drivers/staging/iio/addac/adt7316.c
@@ -551,31 +551,6 @@ static IIO_DEVICE_ATTR(enable_smbus_timeout, S_IRUGO | S_IWUSR,
adt7316_store_enable_smbus_timeout,
0);
-
-static ssize_t adt7316_store_reset(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- struct iio_dev *dev_info = dev_to_iio_dev(dev);
- struct adt7316_chip_info *chip = iio_priv(dev_info);
- u8 config2;
- int ret;
-
- config2 = chip->config2 | ADT7316_RESET;
-
- ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG2, config2);
- if (ret)
- return -EIO;
-
- return len;
-}
-
-static IIO_DEVICE_ATTR(reset, S_IWUSR,
- NULL,
- adt7316_store_reset,
- 0);
-
static ssize_t adt7316_show_powerdown(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -1675,7 +1650,6 @@ static IIO_DEVICE_ATTR(bus_type, S_IRUGO, adt7316_show_bus_type, NULL, 0);
static struct attribute *adt7316_attributes[] = {
&iio_dev_attr_all_modes.dev_attr.attr,
&iio_dev_attr_mode.dev_attr.attr,
- &iio_dev_attr_reset.dev_attr.attr,
&iio_dev_attr_enabled.dev_attr.attr,
&iio_dev_attr_ad_channel.dev_attr.attr,
&iio_dev_attr_all_ad_channels.dev_attr.attr,
@@ -1719,7 +1693,6 @@ static struct attribute *adt7516_attributes[] = {
&iio_dev_attr_all_modes.dev_attr.attr,
&iio_dev_attr_mode.dev_attr.attr,
&iio_dev_attr_select_ex_temp.dev_attr.attr,
- &iio_dev_attr_reset.dev_attr.attr,
&iio_dev_attr_enabled.dev_attr.attr,
&iio_dev_attr_ad_channel.dev_attr.attr,
&iio_dev_attr_all_ad_channels.dev_attr.attr,
diff --git a/drivers/staging/iio/gyro/Kconfig b/drivers/staging/iio/gyro/Kconfig
index b4333715536e..88b199bb2926 100644
--- a/drivers/staging/iio/gyro/Kconfig
+++ b/drivers/staging/iio/gyro/Kconfig
@@ -10,16 +10,4 @@ config ADIS16060
Say yes here to build support for Analog Devices adis16060 wide bandwidth
yaw rate gyroscope with SPI.
-config ADIS16260
- tristate "Analog Devices ADIS16260 Digital Gyroscope Sensor SPI driver"
- depends on SPI
- select IIO_ADIS_LIB
- select IIO_ADIS_LIB_BUFFER if IIO_BUFFER
- help
- Say yes here to build support for Analog Devices ADIS16260 ADIS16265
- ADIS16250 ADIS16255 and ADIS16251 programmable digital gyroscope sensors.
-
- This driver can also be built as a module. If so, the module
- will be called adis16260.
-
endmenu
diff --git a/drivers/staging/iio/gyro/Makefile b/drivers/staging/iio/gyro/Makefile
index 975f95b141da..cf22d6d55e27 100644
--- a/drivers/staging/iio/gyro/Makefile
+++ b/drivers/staging/iio/gyro/Makefile
@@ -4,6 +4,3 @@
adis16060-y := adis16060_core.o
obj-$(CONFIG_ADIS16060) += adis16060.o
-
-adis16260-y := adis16260_core.o
-obj-$(CONFIG_ADIS16260) += adis16260.o
diff --git a/drivers/staging/iio/gyro/adis16260.h b/drivers/staging/iio/gyro/adis16260.h
deleted file mode 100644
index df3c0b7e954a..000000000000
--- a/drivers/staging/iio/gyro/adis16260.h
+++ /dev/null
@@ -1,98 +0,0 @@
-#ifndef SPI_ADIS16260_H_
-#define SPI_ADIS16260_H_
-
-#include "adis16260_platform_data.h"
-#include <linux/iio/imu/adis.h>
-
-#define ADIS16260_STARTUP_DELAY 220 /* ms */
-
-#define ADIS16260_FLASH_CNT 0x00 /* Flash memory write count */
-#define ADIS16260_SUPPLY_OUT 0x02 /* Power supply measurement */
-#define ADIS16260_GYRO_OUT 0x04 /* X-axis gyroscope output */
-#define ADIS16260_AUX_ADC 0x0A /* analog input channel measurement */
-#define ADIS16260_TEMP_OUT 0x0C /* internal temperature measurement */
-#define ADIS16260_ANGL_OUT 0x0E /* angle displacement */
-#define ADIS16260_GYRO_OFF 0x14 /* Calibration, offset/bias adjustment */
-#define ADIS16260_GYRO_SCALE 0x16 /* Calibration, scale adjustment */
-#define ADIS16260_ALM_MAG1 0x20 /* Alarm 1 magnitude/polarity setting */
-#define ADIS16260_ALM_MAG2 0x22 /* Alarm 2 magnitude/polarity setting */
-#define ADIS16260_ALM_SMPL1 0x24 /* Alarm 1 dynamic rate of change setting */
-#define ADIS16260_ALM_SMPL2 0x26 /* Alarm 2 dynamic rate of change setting */
-#define ADIS16260_ALM_CTRL 0x28 /* Alarm control */
-#define ADIS16260_AUX_DAC 0x30 /* Auxiliary DAC data */
-#define ADIS16260_GPIO_CTRL 0x32 /* Control, digital I/O line */
-#define ADIS16260_MSC_CTRL 0x34 /* Control, data ready, self-test settings */
-#define ADIS16260_SMPL_PRD 0x36 /* Control, internal sample rate */
-#define ADIS16260_SENS_AVG 0x38 /* Control, dynamic range, filtering */
-#define ADIS16260_SLP_CNT 0x3A /* Control, sleep mode initiation */
-#define ADIS16260_DIAG_STAT 0x3C /* Diagnostic, error flags */
-#define ADIS16260_GLOB_CMD 0x3E /* Control, global commands */
-#define ADIS16260_LOT_ID1 0x52 /* Lot Identification Code 1 */
-#define ADIS16260_LOT_ID2 0x54 /* Lot Identification Code 2 */
-#define ADIS16260_PROD_ID 0x56 /* Product identifier;
- * convert to decimal = 16,265/16,260 */
-#define ADIS16260_SERIAL_NUM 0x58 /* Serial number */
-
-#define ADIS16260_ERROR_ACTIVE (1<<14)
-#define ADIS16260_NEW_DATA (1<<15)
-
-/* MSC_CTRL */
-#define ADIS16260_MSC_CTRL_MEM_TEST (1<<11)
-/* Internal self-test enable */
-#define ADIS16260_MSC_CTRL_INT_SELF_TEST (1<<10)
-#define ADIS16260_MSC_CTRL_NEG_SELF_TEST (1<<9)
-#define ADIS16260_MSC_CTRL_POS_SELF_TEST (1<<8)
-#define ADIS16260_MSC_CTRL_DATA_RDY_EN (1<<2)
-#define ADIS16260_MSC_CTRL_DATA_RDY_POL_HIGH (1<<1)
-#define ADIS16260_MSC_CTRL_DATA_RDY_DIO2 (1<<0)
-
-/* SMPL_PRD */
-/* Time base (tB): 0 = 1.953 ms, 1 = 60.54 ms */
-#define ADIS16260_SMPL_PRD_TIME_BASE (1<<7)
-#define ADIS16260_SMPL_PRD_DIV_MASK 0x7F
-
-/* SLP_CNT */
-#define ADIS16260_SLP_CNT_POWER_OFF 0x80
-
-/* DIAG_STAT */
-#define ADIS16260_DIAG_STAT_ALARM2 (1<<9)
-#define ADIS16260_DIAG_STAT_ALARM1 (1<<8)
-#define ADIS16260_DIAG_STAT_FLASH_CHK_BIT 6
-#define ADIS16260_DIAG_STAT_SELF_TEST_BIT 5
-#define ADIS16260_DIAG_STAT_OVERFLOW_BIT 4
-#define ADIS16260_DIAG_STAT_SPI_FAIL_BIT 3
-#define ADIS16260_DIAG_STAT_FLASH_UPT_BIT 2
-#define ADIS16260_DIAG_STAT_POWER_HIGH_BIT 1
-#define ADIS16260_DIAG_STAT_POWER_LOW_BIT 0
-
-/* GLOB_CMD */
-#define ADIS16260_GLOB_CMD_SW_RESET (1<<7)
-#define ADIS16260_GLOB_CMD_FLASH_UPD (1<<3)
-#define ADIS16260_GLOB_CMD_DAC_LATCH (1<<2)
-#define ADIS16260_GLOB_CMD_FAC_CALIB (1<<1)
-#define ADIS16260_GLOB_CMD_AUTO_NULL (1<<0)
-
-#define ADIS16260_SPI_SLOW (u32)(300 * 1000)
-#define ADIS16260_SPI_BURST (u32)(1000 * 1000)
-#define ADIS16260_SPI_FAST (u32)(2000 * 1000)
-
-/**
- * struct adis16260_state - device instance specific data
- * @negate: negate the scale parameter
- **/
-struct adis16260_state {
- unsigned negate:1;
- struct adis adis;
-};
-
-/* At the moment triggers are only used for ring buffer
- * filling. This may change!
- */
-
-#define ADIS16260_SCAN_GYRO 0
-#define ADIS16260_SCAN_SUPPLY 1
-#define ADIS16260_SCAN_AUX_ADC 2
-#define ADIS16260_SCAN_TEMP 3
-#define ADIS16260_SCAN_ANGL 4
-
-#endif /* SPI_ADIS16260_H_ */
diff --git a/drivers/staging/iio/gyro/adis16260_platform_data.h b/drivers/staging/iio/gyro/adis16260_platform_data.h
deleted file mode 100644
index 12802e97be92..000000000000
--- a/drivers/staging/iio/gyro/adis16260_platform_data.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * ADIS16260 Programmable Digital Gyroscope Sensor Driver Platform Data
- *
- * Based on adis16255.h Matthia Brugger <m_brugger&web.de>
- *
- * Copyright (C) 2010 Fraunhofer Institute for Integrated Circuits
- *
- * Licensed under the GPL-2 or later.
- */
-
-/**
- * struct adis16260_platform_data - instance specific data
- * @direction: x y or z
- * @negate: flag to indicate value should be inverted.
- **/
-struct adis16260_platform_data {
- char direction;
- unsigned negate:1;
-};
diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c
index 82478a59e42e..351936c3efd6 100644
--- a/drivers/staging/iio/light/isl29018.c
+++ b/drivers/staging/iio/light/isl29018.c
@@ -550,11 +550,10 @@ static int isl29018_probe(struct i2c_client *client,
struct iio_dev *indio_dev;
int err;
- indio_dev = iio_device_alloc(sizeof(*chip));
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
if (indio_dev == NULL) {
dev_err(&client->dev, "iio allocation fails\n");
- err = -ENOMEM;
- goto exit;
+ return -ENOMEM;
}
chip = iio_priv(indio_dev);
@@ -572,12 +571,12 @@ static int isl29018_probe(struct i2c_client *client,
if (IS_ERR(chip->regmap)) {
err = PTR_ERR(chip->regmap);
dev_err(chip->dev, "regmap initialization failed: %d\n", err);
- goto exit;
+ return err;
}
err = isl29018_chip_init(chip);
if (err)
- goto exit_iio_free;
+ return err;
indio_dev->info = &isl29108_info;
indio_dev->channels = isl29018_channels;
@@ -588,14 +587,10 @@ static int isl29018_probe(struct i2c_client *client,
err = iio_device_register(indio_dev);
if (err) {
dev_err(&client->dev, "iio registration fails\n");
- goto exit_iio_free;
+ return err;
}
return 0;
-exit_iio_free:
- iio_device_free(indio_dev);
-exit:
- return err;
}
static int isl29018_remove(struct i2c_client *client)
@@ -604,7 +599,6 @@ static int isl29018_remove(struct i2c_client *client)
dev_dbg(&client->dev, "%s()\n", __func__);
iio_device_unregister(indio_dev);
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/light/isl29028.c b/drivers/staging/iio/light/isl29028.c
index 8bb0d03627f2..6014625920b0 100644
--- a/drivers/staging/iio/light/isl29028.c
+++ b/drivers/staging/iio/light/isl29028.c
@@ -482,7 +482,7 @@ static int isl29028_probe(struct i2c_client *client,
struct iio_dev *indio_dev;
int ret;
- indio_dev = iio_device_alloc(sizeof(*chip));
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
if (!indio_dev) {
dev_err(&client->dev, "iio allocation fails\n");
return -ENOMEM;
@@ -498,13 +498,13 @@ static int isl29028_probe(struct i2c_client *client,
if (IS_ERR(chip->regmap)) {
ret = PTR_ERR(chip->regmap);
dev_err(chip->dev, "regmap initialization failed: %d\n", ret);
- goto exit_iio_free;
+ return ret;
}
ret = isl29028_chip_init(chip);
if (ret < 0) {
dev_err(chip->dev, "chip initialization failed: %d\n", ret);
- goto exit_iio_free;
+ return ret;
}
indio_dev->info = &isl29028_info;
@@ -517,13 +517,9 @@ static int isl29028_probe(struct i2c_client *client,
if (ret < 0) {
dev_err(chip->dev, "iio registration fails with error %d\n",
ret);
- goto exit_iio_free;
+ return ret;
}
return 0;
-
-exit_iio_free:
- iio_device_free(indio_dev);
- return ret;
}
static int isl29028_remove(struct i2c_client *client)
@@ -531,7 +527,6 @@ static int isl29028_remove(struct i2c_client *client)
struct iio_dev *indio_dev = i2c_get_clientdata(client);
iio_device_unregister(indio_dev);
- iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c
index 86c6bf9d5dd8..d2748c329eae 100644
--- a/drivers/staging/iio/magnetometer/hmc5843.c
+++ b/drivers/staging/iio/magnetometer/hmc5843.c
@@ -20,12 +20,10 @@
*/
#include <linux/module.h>
-#include <linux/init.h>
#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/types.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
+#include <linux/delay.h>
#define HMC5843_CONFIG_REG_A 0x00
#define HMC5843_CONFIG_REG_B 0x01
@@ -42,9 +40,6 @@
#define HMC5883_DATA_OUT_Y_MSB_REG 0x07
#define HMC5883_DATA_OUT_Y_LSB_REG 0x08
#define HMC5843_STATUS_REG 0x09
-#define HMC5843_ID_REG_A 0x0A
-#define HMC5843_ID_REG_B 0x0B
-#define HMC5843_ID_REG_C 0x0C
enum hmc5843_ids {
HMC5843_ID,
@@ -53,14 +48,6 @@ enum hmc5843_ids {
};
/*
- * Beware: identification of the HMC5883 is still "H43";
- * I2C address is also unchanged
- */
-#define HMC5843_ID_REG_LENGTH 0x03
-#define HMC5843_ID_STRING "H43"
-#define HMC5843_I2C_ADDRESS 0x1E
-
-/*
* Range gain settings in (+-)Ga
* Beware: HMC5843 and HMC5883 have different recommended sensor field
* ranges; default corresponds to +-1.0 Ga and +-1.3 Ga, respectively
@@ -185,14 +172,9 @@ static const char * const hmc5883_regval_to_sample_freq[] = {
"0.75", "1.5", "3", "7.5", "15", "30", "75",
};
-/* Addresses to scan: 0x1E */
-static const unsigned short normal_i2c[] = { HMC5843_I2C_ADDRESS,
- I2C_CLIENT_END };
-
/* Describe chip variants */
struct hmc5843_chip_info {
const struct iio_chan_spec *channels;
- int num_channels;
const char * const *regval_to_sample_freq;
const int *regval_to_input_field_mga;
const int *regval_to_nanoscale;
@@ -225,18 +207,29 @@ static int hmc5843_read_measurement(struct iio_dev *indio_dev,
struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
struct hmc5843_data *data = iio_priv(indio_dev);
s32 result;
+ int tries = 150;
mutex_lock(&data->lock);
- result = i2c_smbus_read_byte_data(client, HMC5843_STATUS_REG);
- while (!(result & HMC5843_DATA_READY))
- result = i2c_smbus_read_byte_data(client, HMC5843_STATUS_REG);
+ while (tries-- > 0) {
+ result = i2c_smbus_read_byte_data(client,
+ HMC5843_STATUS_REG);
+ if (result & HMC5843_DATA_READY)
+ break;
+ msleep(20);
+ }
+
+ if (tries < 0) {
+ dev_err(&client->dev, "data not ready\n");
+ mutex_unlock(&data->lock);
+ return -EIO;
+ }
- result = i2c_smbus_read_word_data(client, address);
+ result = i2c_smbus_read_word_swapped(client, address);
mutex_unlock(&data->lock);
if (result < 0)
return -EINVAL;
- *val = (s16)swab16((u16)result);
+ *val = result;
return IIO_VAL_INT;
}
@@ -559,14 +552,14 @@ static int hmc5843_read_raw(struct iio_dev *indio_dev,
return -EINVAL;
}
-#define HMC5843_CHANNEL(axis, add) \
+#define HMC5843_CHANNEL(axis, addr) \
{ \
.type = IIO_MAGN, \
.modified = 1, \
.channel2 = IIO_MOD_##axis, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
- .address = add \
+ .address = addr \
}
static const struct iio_chan_spec hmc5843_channels[] = {
@@ -597,7 +590,6 @@ static const struct attribute_group hmc5843_group = {
static const struct hmc5843_chip_info hmc5843_chip_info_tbl[] = {
[HMC5843_ID] = {
.channels = hmc5843_channels,
- .num_channels = ARRAY_SIZE(hmc5843_channels),
.regval_to_sample_freq = hmc5843_regval_to_sample_freq,
.regval_to_input_field_mga =
hmc5843_regval_to_input_field_mga,
@@ -605,7 +597,6 @@ static const struct hmc5843_chip_info hmc5843_chip_info_tbl[] = {
},
[HMC5883_ID] = {
.channels = hmc5883_channels,
- .num_channels = ARRAY_SIZE(hmc5883_channels),
.regval_to_sample_freq = hmc5883_regval_to_sample_freq,
.regval_to_input_field_mga =
hmc5883_regval_to_input_field_mga,
@@ -613,7 +604,6 @@ static const struct hmc5843_chip_info hmc5843_chip_info_tbl[] = {
},
[HMC5883L_ID] = {
.channels = hmc5883_channels,
- .num_channels = ARRAY_SIZE(hmc5883_channels),
.regval_to_sample_freq = hmc5883_regval_to_sample_freq,
.regval_to_input_field_mga =
hmc5883l_regval_to_input_field_mga,
@@ -621,25 +611,6 @@ static const struct hmc5843_chip_info hmc5843_chip_info_tbl[] = {
},
};
-static int hmc5843_detect(struct i2c_client *client,
- struct i2c_board_info *info)
-{
- unsigned char id_str[HMC5843_ID_REG_LENGTH];
-
- if (client->addr != HMC5843_I2C_ADDRESS)
- return -ENODEV;
-
- if (i2c_smbus_read_i2c_block_data(client, HMC5843_ID_REG_A,
- HMC5843_ID_REG_LENGTH, id_str)
- != HMC5843_ID_REG_LENGTH)
- return -ENODEV;
-
- if (0 != strncmp(id_str, HMC5843_ID_STRING, HMC5843_ID_REG_LENGTH))
- return -ENODEV;
-
- return 0;
-}
-
/* Called when we have found a new HMC58X3 */
static void hmc5843_init_client(struct i2c_client *client,
const struct i2c_device_id *id)
@@ -649,7 +620,7 @@ static void hmc5843_init_client(struct i2c_client *client,
data->variant = &hmc5843_chip_info_tbl[id->driver_data];
indio_dev->channels = data->variant->channels;
- indio_dev->num_channels = data->variant->num_channels;
+ indio_dev->num_channels = 3;
hmc5843_set_meas_conf(client, data->meas_conf);
hmc5843_set_rate(client, data->rate);
hmc5843_configure(client, data->operating_mode);
@@ -756,8 +727,6 @@ static struct i2c_driver hmc5843_driver = {
.id_table = hmc5843_id,
.probe = hmc5843_probe,
.remove = hmc5843_remove,
- .detect = hmc5843_detect,
- .address_list = normal_i2c,
};
module_i2c_driver(hmc5843_driver);
diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c
index e5943e2287cf..74025fbae679 100644
--- a/drivers/staging/iio/meter/ade7753.c
+++ b/drivers/staging/iio/meter/ade7753.c
@@ -225,21 +225,6 @@ static int ade7753_reset(struct device *dev)
return ade7753_spi_write_reg_16(dev, ADE7753_MODE, val);
}
-static ssize_t ade7753_write_reset(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- if (len < 1)
- return -1;
- switch (buf[0]) {
- case '1':
- case 'y':
- case 'Y':
- return ade7753_reset(dev);
- }
- return -1;
-}
-
static IIO_DEV_ATTR_AENERGY(ade7753_read_24bit, ADE7753_AENERGY);
static IIO_DEV_ATTR_LAENERGY(ade7753_read_24bit, ADE7753_LAENERGY);
static IIO_DEV_ATTR_VAENERGY(ade7753_read_24bit, ADE7753_VAENERGY);
@@ -458,8 +443,6 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
ade7753_read_frequency,
ade7753_write_frequency);
-static IIO_DEV_ATTR_RESET(ade7753_write_reset);
-
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("27900 14000 7000 3500");
static struct attribute *ade7753_attributes[] = {
@@ -468,7 +451,6 @@ static struct attribute *ade7753_attributes[] = {
&iio_const_attr_in_temp_scale.dev_attr.attr,
&iio_dev_attr_sampling_frequency.dev_attr.attr,
&iio_const_attr_sampling_frequency_available.dev_attr.attr,
- &iio_dev_attr_reset.dev_attr.attr,
&iio_dev_attr_phcal.dev_attr.attr,
&iio_dev_attr_cfden.dev_attr.attr,
&iio_dev_attr_aenergy.dev_attr.attr,
diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c
index 7b6503bf9a74..f649ebe55a04 100644
--- a/drivers/staging/iio/meter/ade7754.c
+++ b/drivers/staging/iio/meter/ade7754.c
@@ -224,22 +224,6 @@ static int ade7754_reset(struct device *dev)
return ade7754_spi_write_reg_8(dev, ADE7754_OPMODE, val);
}
-
-static ssize_t ade7754_write_reset(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- if (len < 1)
- return -1;
- switch (buf[0]) {
- case '1':
- case 'y':
- case 'Y':
- return ade7754_reset(dev);
- }
- return -1;
-}
-
static IIO_DEV_ATTR_AENERGY(ade7754_read_24bit, ADE7754_AENERGY);
static IIO_DEV_ATTR_LAENERGY(ade7754_read_24bit, ADE7754_LAENERGY);
static IIO_DEV_ATTR_VAENERGY(ade7754_read_24bit, ADE7754_VAENERGY);
@@ -478,8 +462,6 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
ade7754_read_frequency,
ade7754_write_frequency);
-static IIO_DEV_ATTR_RESET(ade7754_write_reset);
-
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("26000 13000 65000 33000");
static struct attribute *ade7754_attributes[] = {
@@ -488,7 +470,6 @@ static struct attribute *ade7754_attributes[] = {
&iio_const_attr_in_temp_scale.dev_attr.attr,
&iio_dev_attr_sampling_frequency.dev_attr.attr,
&iio_const_attr_sampling_frequency_available.dev_attr.attr,
- &iio_dev_attr_reset.dev_attr.attr,
&iio_dev_attr_aenergy.dev_attr.attr,
&iio_dev_attr_laenergy.dev_attr.attr,
&iio_dev_attr_vaenergy.dev_attr.attr,
diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c
index 8f5bcfab3563..6005d4aab0c3 100644
--- a/drivers/staging/iio/meter/ade7758_core.c
+++ b/drivers/staging/iio/meter/ade7758_core.c
@@ -313,21 +313,6 @@ static int ade7758_reset(struct device *dev)
return ret;
}
-static ssize_t ade7758_write_reset(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- if (len < 1)
- return -1;
- switch (buf[0]) {
- case '1':
- case 'y':
- case 'Y':
- return ade7758_reset(dev);
- }
- return len;
-}
-
static IIO_DEV_ATTR_VPEAK(S_IWUSR | S_IRUGO,
ade7758_read_8bit,
ade7758_write_8bit,
@@ -591,8 +576,6 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
ade7758_read_frequency,
ade7758_write_frequency);
-static IIO_DEV_ATTR_RESET(ade7758_write_reset);
-
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("26040 13020 6510 3255");
static struct attribute *ade7758_attributes[] = {
@@ -601,7 +584,6 @@ static struct attribute *ade7758_attributes[] = {
&iio_const_attr_in_temp_scale.dev_attr.attr,
&iio_dev_attr_sampling_frequency.dev_attr.attr,
&iio_const_attr_sampling_frequency_available.dev_attr.attr,
- &iio_dev_attr_reset.dev_attr.attr,
&iio_dev_attr_awatthr.dev_attr.attr,
&iio_dev_attr_bwatthr.dev_attr.attr,
&iio_dev_attr_cwatthr.dev_attr.attr,
diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c
index b29e2d5d9937..7d5db7175578 100644
--- a/drivers/staging/iio/meter/ade7758_ring.c
+++ b/drivers/staging/iio/meter/ade7758_ring.c
@@ -54,7 +54,7 @@ out:
return ret;
}
-/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
+/* Whilst this makes a lot of calls to iio_sw_ring functions - it is too device
* specific to be rolled into the core.
*/
static irqreturn_t ade7758_trigger_handler(int irq, void *p)
diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c
index 17dc373e1082..d214ac4932cb 100644
--- a/drivers/staging/iio/meter/ade7759.c
+++ b/drivers/staging/iio/meter/ade7759.c
@@ -229,21 +229,6 @@ static int ade7759_reset(struct device *dev)
return ret;
}
-static ssize_t ade7759_write_reset(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- if (len < 1)
- return -1;
- switch (buf[0]) {
- case '1':
- case 'y':
- case 'Y':
- return ade7759_reset(dev);
- }
- return -1;
-}
-
static IIO_DEV_ATTR_AENERGY(ade7759_read_40bit, ADE7759_AENERGY);
static IIO_DEV_ATTR_CFDEN(S_IWUSR | S_IRUGO,
ade7759_read_16bit,
@@ -418,8 +403,6 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
ade7759_read_frequency,
ade7759_write_frequency);
-static IIO_DEV_ATTR_RESET(ade7759_write_reset);
-
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("27900 14000 7000 3500");
static struct attribute *ade7759_attributes[] = {
@@ -428,7 +411,6 @@ static struct attribute *ade7759_attributes[] = {
&iio_const_attr_in_temp_scale.dev_attr.attr,
&iio_dev_attr_sampling_frequency.dev_attr.attr,
&iio_const_attr_sampling_frequency_available.dev_attr.attr,
- &iio_dev_attr_reset.dev_attr.attr,
&iio_dev_attr_phcal.dev_attr.attr,
&iio_dev_attr_cfden.dev_attr.attr,
&iio_dev_attr_aenergy.dev_attr.attr,
diff --git a/drivers/staging/iio/meter/ade7854.c b/drivers/staging/iio/meter/ade7854.c
index c642da84842a..e8379c0f1173 100644
--- a/drivers/staging/iio/meter/ade7854.c
+++ b/drivers/staging/iio/meter/ade7854.c
@@ -186,22 +186,6 @@ static int ade7854_reset(struct device *dev)
return st->write_reg_16(dev, ADE7854_CONFIG, val);
}
-
-static ssize_t ade7854_write_reset(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- if (len < 1)
- return -1;
- switch (buf[0]) {
- case '1':
- case 'y':
- case 'Y':
- return ade7854_reset(dev);
- }
- return -1;
-}
-
static IIO_DEV_ATTR_AIGAIN(S_IWUSR | S_IRUGO,
ade7854_read_24bit,
ade7854_write_24bit,
@@ -468,8 +452,6 @@ err_ret:
return ret;
}
-static IIO_DEV_ATTR_RESET(ade7854_write_reset);
-
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("8000");
static IIO_CONST_ATTR(name, "ade7854");
@@ -515,7 +497,6 @@ static struct attribute *ade7854_attributes[] = {
&iio_dev_attr_bvahr.dev_attr.attr,
&iio_dev_attr_cvahr.dev_attr.attr,
&iio_const_attr_sampling_frequency_available.dev_attr.attr,
- &iio_dev_attr_reset.dev_attr.attr,
&iio_const_attr_name.dev_attr.attr,
&iio_dev_attr_vpeak.dev_attr.attr,
&iio_dev_attr_ipeak.dev_attr.attr,
diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index 0d3356d4b7d2..dcdadbbcf7e8 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -192,21 +192,6 @@ static inline int ad2s1210_soft_reset(struct ad2s1210_state *st)
return ad2s1210_config_write(st, 0x0);
}
-static ssize_t ad2s1210_store_softreset(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
- int ret;
-
- mutex_lock(&st->lock);
- ret = ad2s1210_soft_reset(st);
- mutex_unlock(&st->lock);
-
- return ret < 0 ? ret : len;
-}
-
static ssize_t ad2s1210_show_fclkin(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -536,8 +521,6 @@ error_ret:
return ret;
}
-static IIO_DEVICE_ATTR(reset, S_IWUSR,
- NULL, ad2s1210_store_softreset, 0);
static IIO_DEVICE_ATTR(fclkin, S_IRUGO | S_IWUSR,
ad2s1210_show_fclkin, ad2s1210_store_fclkin, 0);
static IIO_DEVICE_ATTR(fexcit, S_IRUGO | S_IWUSR,
@@ -587,7 +570,6 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
};
static struct attribute *ad2s1210_attributes[] = {
- &iio_dev_attr_reset.dev_attr.attr,
&iio_dev_attr_fclkin.dev_attr.attr,
&iio_dev_attr_fexcit.dev_attr.attr,
&iio_dev_attr_control.dev_attr.attr,