diff options
107 files changed, 2126 insertions, 1144 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index dda81ffae5cf..45ae709db4ff 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -351,6 +351,7 @@ Description: 6kohm_to_gnd: connected to ground via a 6kOhm resistor, 20kohm_to_gnd: connected to ground via a 20kOhm resistor, 100kohm_to_gnd: connected to ground via an 100kOhm resistor, + 500kohm_to_gnd: connected to ground via a 500kOhm resistor, three_state: left floating. For a list of available output power down options read outX_powerdown_mode_available. If Y is not present the @@ -792,3 +793,11 @@ Contact: linux-iio@vger.kernel.org Description: This attribute is used to read the amount of quadrature error present in the device at a given time. + +What: /sys/bus/iio/devices/iio:deviceX/store_eeprom +KernelVersion: 3.4.0 +Contact: linux-iio@vger.kernel.org +Description: + Writing '1' stores the current device configuration into + on-chip EEPROM. After power-up or chip reset the device will + automatically load the saved configuration. diff --git a/Documentation/ABI/testing/sysfs-bus-iio-frequency-ad9523 b/Documentation/ABI/testing/sysfs-bus-iio-frequency-ad9523 index 2ce9c3f68eee..a91aeabe7b24 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio-frequency-ad9523 +++ b/Documentation/ABI/testing/sysfs-bus-iio-frequency-ad9523 @@ -18,14 +18,6 @@ Description: Reading returns either '1' or '0'. '1' means that the pllY is locked. -What: /sys/bus/iio/devices/iio:deviceX/store_eeprom -KernelVersion: 3.4.0 -Contact: linux-iio@vger.kernel.org -Description: - Writing '1' stores the current device configuration into - on-chip EEPROM. After power-up or chip reset the device will - automatically load the saved configuration. - What: /sys/bus/iio/devices/iio:deviceX/sync_dividers KernelVersion: 3.4.0 Contact: linux-iio@vger.kernel.org diff --git a/Documentation/ABI/testing/sysfs-bus-iio-frequency-adf4350 b/Documentation/ABI/testing/sysfs-bus-iio-frequency-adf4350 index d89aded01c5a..1254457a726e 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio-frequency-adf4350 +++ b/Documentation/ABI/testing/sysfs-bus-iio-frequency-adf4350 @@ -18,4 +18,4 @@ Description: adjust the reference frequency accordingly. The value written has no effect until out_altvoltageY_frequency is updated. Consider to use out_altvoltageY_powerdown to power - down the PLL and it's RFOut buffers during REFin changes. + down the PLL and its RFOut buffers during REFin changes. diff --git a/Documentation/devicetree/bindings/iio/adc/nuvoton-nau7802.txt b/Documentation/devicetree/bindings/iio/adc/nuvoton-nau7802.txt new file mode 100644 index 000000000000..e9582e6fe350 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/nuvoton-nau7802.txt @@ -0,0 +1,18 @@ +* Nuvoton NAU7802 Analog to Digital Converter (ADC) + +Required properties: + - compatible: Should be "nuvoton,nau7802" + - reg: Should contain the ADC I2C address + +Optional properties: + - nuvoton,vldo: Internal reference voltage in millivolts to be + configured valid values are between 2400 mV and 4500 mV. + - interrupts: IRQ line for the ADC. If not used the driver will use + polling. + +Example: +adc2: nau7802@2a { + compatible = "nuvoton,nau7802"; + reg = <0x2a>; + nuvoton,vldo = <3000>; +}; diff --git a/Documentation/devicetree/bindings/iio/light/apds9300.txt b/Documentation/devicetree/bindings/iio/light/apds9300.txt new file mode 100644 index 000000000000..d6f66c73ddbf --- /dev/null +++ b/Documentation/devicetree/bindings/iio/light/apds9300.txt @@ -0,0 +1,22 @@ +* Avago APDS9300 ambient light sensor + +http://www.avagotech.com/docs/AV02-1077EN + +Required properties: + + - compatible : should be "avago,apds9300" + - reg : the I2C address of the sensor + +Optional properties: + + - interrupt-parent : should be the phandle for the interrupt controller + - interrupts : interrupt mapping for GPIO IRQ + +Example: + +apds9300@39 { + compatible = "avago,apds9300"; + reg = <0x39>; + interrupt-parent = <&gpio2>; + interrupts = <29 8>; +}; diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 366ce9b87240..ec4d713674fa 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -11,6 +11,7 @@ amcc Applied Micro Circuits Corporation (APM, formally AMCC) apm Applied Micro Circuits Corporation (APM) arm ARM Ltd. atmel Atmel Corporation +avago Avago Technologies bosch Bosch Sensortec GmbH brcm Broadcom Corporation cavium Cavium, Inc. diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt index b4671459857f..1d3233292989 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.txt @@ -237,6 +237,10 @@ MEM devm_kzalloc() devm_kfree() +IIO + devm_iio_device_alloc() + devm_iio_device_free() + IO region devm_request_region() devm_request_mem_region() 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, diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h index 72b26940730d..e51f65480ea5 100644 --- a/include/linux/iio/common/st_sensors.h +++ b/include/linux/iio/common/st_sensors.h @@ -17,6 +17,8 @@ #include <linux/iio/trigger.h> #include <linux/bitops.h> +#include <linux/platform_data/st_sensors_pdata.h> + #define ST_SENSORS_TX_MAX_LENGTH 2 #define ST_SENSORS_RX_MAX_LENGTH 6 @@ -118,14 +120,16 @@ struct st_sensor_bdu { /** * struct st_sensor_data_ready_irq - ST sensor device data-ready interrupt * @addr: address of the register. - * @mask: mask to write the on/off value. + * @mask_int1: mask to enable/disable IRQ on INT1 pin. + * @mask_int2: mask to enable/disable IRQ on INT2 pin. * struct ig1 - represents the Interrupt Generator 1 of sensors. * @en_addr: address of the enable ig1 register. * @en_mask: mask to write the on/off value for enable. */ struct st_sensor_data_ready_irq { u8 addr; - u8 mask; + u8 mask_int1; + u8 mask_int2; struct { u8 en_addr; u8 en_mask; @@ -201,6 +205,7 @@ struct st_sensors { * @buffer_data: Data used by buffer part. * @odr: Output data rate of the sensor [Hz]. * num_data_channels: Number of data channels used in buffer. + * @drdy_int_pin: Redirect DRDY on pin 1 (1) or pin 2 (2). * @get_irq_data_ready: Function to get the IRQ used for data ready signal. * @tf: Transfer function structure used by I/O operations. * @tb: Transfer buffers and mutex used by I/O operations. @@ -219,6 +224,8 @@ struct st_sensor_data { unsigned int odr; unsigned int num_data_channels; + u8 drdy_int_pin; + unsigned int (*get_irq_data_ready) (struct iio_dev *indio_dev); const struct st_sensor_transfer_function *tf; @@ -249,7 +256,8 @@ static inline void st_sensors_deallocate_trigger(struct iio_dev *indio_dev) } #endif -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 st_sensors_set_enable(struct iio_dev *indio_dev, bool enable); diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 3d35b7023591..09ebe0a4d8e6 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -532,6 +532,31 @@ static inline struct iio_dev *iio_priv_to_dev(void *priv) void iio_device_free(struct iio_dev *indio_dev); /** + * devm_iio_device_alloc - Resource-managed iio_device_alloc() + * @dev: Device to allocate iio_dev for + * @sizeof_priv: Space to allocate for private structure. + * + * Managed iio_device_alloc. iio_dev allocated with this function is + * automatically freed on driver detach. + * + * If an iio_dev allocated with this function needs to be freed separately, + * devm_iio_device_free() must be used. + * + * RETURNS: + * Pointer to allocated iio_dev on success, NULL on failure. + */ +struct iio_dev *devm_iio_device_alloc(struct device *dev, int sizeof_priv); + +/** + * devm_iio_device_free - Resource-managed iio_device_free() + * @dev: Device this iio_dev belongs to + * @indio_dev: the iio_dev associated with the device + * + * Free iio_dev allocated with devm_iio_device_alloc(). + */ +void devm_iio_device_free(struct device *dev, struct iio_dev *indio_dev); + +/** * iio_buffer_enabled() - helper function to test if the buffer is enabled * @indio_dev: IIO device structure for device **/ diff --git a/include/linux/iio/sysfs.h b/include/linux/iio/sysfs.h index b7a934b9431b..2958c960003a 100644 --- a/include/linux/iio/sysfs.h +++ b/include/linux/iio/sysfs.h @@ -73,11 +73,6 @@ struct iio_const_attr { .dev_attr = __ATTR(_name, S_IRUGO, iio_read_const_attr, NULL)} /* Generic attributes of onetype or another */ -/** - * IIO_DEV_ATTR_RESET: resets the device - **/ -#define IIO_DEV_ATTR_RESET(_store) \ - IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, _store, 0) /** * IIO_DEV_ATTR_SAMP_FREQ - sets any internal clock frequency diff --git a/include/linux/platform_data/st_sensors_pdata.h b/include/linux/platform_data/st_sensors_pdata.h new file mode 100644 index 000000000000..753839187ba0 --- /dev/null +++ b/include/linux/platform_data/st_sensors_pdata.h @@ -0,0 +1,24 @@ +/* + * STMicroelectronics sensors platform-data driver + * + * Copyright 2013 STMicroelectronics Inc. + * + * Denis Ciocca <denis.ciocca@st.com> + * + * Licensed under the GPL-2. + */ + +#ifndef ST_SENSORS_PDATA_H +#define ST_SENSORS_PDATA_H + +/** + * struct st_sensors_platform_data - Platform data for the ST sensors + * @drdy_int_pin: Redirect DRDY on pin 1 (1) or pin 2 (2). + * Available only for accelerometer and pressure sensors. + * Accelerometer DRDY on LSM330 available only on pin 1 (see datasheet). + */ +struct st_sensors_platform_data { + u8 drdy_int_pin; +}; + +#endif /* ST_SENSORS_PDATA_H */ |