aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/iio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/iio')
-rw-r--r--drivers/staging/iio/Documentation/light/sysfs-bus-iio-light-tsl25836
-rw-r--r--drivers/staging/iio/Documentation/sysfs-bus-iio-light-tsl258320
-rw-r--r--drivers/staging/iio/TODO70
-rw-r--r--drivers/staging/iio/accel/Kconfig10
-rw-r--r--drivers/staging/iio/accel/Makefile3
-rw-r--r--drivers/staging/iio/accel/sca3000.h279
-rw-r--r--drivers/staging/iio/accel/sca3000_core.c1210
-rw-r--r--drivers/staging/iio/accel/sca3000_ring.c350
-rw-r--r--drivers/staging/iio/adc/Makefile1
-rw-r--r--drivers/staging/iio/adc/ad7192.c127
-rw-r--r--drivers/staging/iio/adc/ad7280a.c2
-rw-r--r--drivers/staging/iio/adc/ad7606.c (renamed from drivers/staging/iio/adc/ad7606_core.c)436
-rw-r--r--drivers/staging/iio/adc/ad7606.h58
-rw-r--r--drivers/staging/iio/adc/ad7606_par.c23
-rw-r--r--drivers/staging/iio/adc/ad7606_ring.c102
-rw-r--r--drivers/staging/iio/adc/ad7606_spi.c19
-rw-r--r--drivers/staging/iio/adc/ad7780.c22
-rw-r--r--drivers/staging/iio/adc/ad7816.c2
-rw-r--r--drivers/staging/iio/addac/adt7316.c4
-rw-r--r--drivers/staging/iio/cdc/ad7150.c2
-rw-r--r--drivers/staging/iio/cdc/ad7152.c140
-rw-r--r--drivers/staging/iio/cdc/ad7746.c151
-rw-r--r--drivers/staging/iio/frequency/ad9832.c66
-rw-r--r--drivers/staging/iio/frequency/ad9832.h6
-rw-r--r--drivers/staging/iio/frequency/ad9834.c19
-rw-r--r--drivers/staging/iio/impedance-analyzer/ad5933.c21
-rw-r--r--drivers/staging/iio/light/Kconfig19
-rw-r--r--drivers/staging/iio/light/Makefile2
-rw-r--r--drivers/staging/iio/light/isl29018.c834
-rw-r--r--drivers/staging/iio/light/tsl2583.c963
-rw-r--r--drivers/staging/iio/meter/ade7758_core.c86
-rw-r--r--drivers/staging/iio/ring_hw.h27
32 files changed, 566 insertions, 4514 deletions
diff --git a/drivers/staging/iio/Documentation/light/sysfs-bus-iio-light-tsl2583 b/drivers/staging/iio/Documentation/light/sysfs-bus-iio-light-tsl2583
deleted file mode 100644
index 470f7ad9c073..000000000000
--- a/drivers/staging/iio/Documentation/light/sysfs-bus-iio-light-tsl2583
+++ /dev/null
@@ -1,6 +0,0 @@
-What: /sys/bus/iio/devices/device[n]/in_illuminance0_calibrate
-KernelVersion: 2.6.37
-Contact: linux-iio@vger.kernel.org
-Description:
- This property causes an internal calibration of the als gain trim
- value which is later used in calculating illuminance in lux.
diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio-light-tsl2583 b/drivers/staging/iio/Documentation/sysfs-bus-iio-light-tsl2583
deleted file mode 100644
index 660781df409f..000000000000
--- a/drivers/staging/iio/Documentation/sysfs-bus-iio-light-tsl2583
+++ /dev/null
@@ -1,20 +0,0 @@
-What: /sys/bus/iio/devices/device[n]/lux_table
-KernelVersion: 2.6.37
-Contact: linux-iio@vger.kernel.org
-Description:
- This property gets/sets the table of coefficients
- used in calculating illuminance in lux.
-
-What: /sys/bus/iio/devices/device[n]/illuminance0_calibrate
-KernelVersion: 2.6.37
-Contact: linux-iio@vger.kernel.org
-Description:
- This property causes an internal calibration of the als gain trim
- value which is later used in calculating illuminance in lux.
-
-What: /sys/bus/iio/devices/device[n]/illuminance0_input_target
-KernelVersion: 2.6.37
-Contact: linux-iio@vger.kernel.org
-Description:
- This property is the known externally illuminance (in lux).
- It is used in the process of calibrating the device accuracy.
diff --git a/drivers/staging/iio/TODO b/drivers/staging/iio/TODO
index 93a896883e37..4922402e2e98 100644
--- a/drivers/staging/iio/TODO
+++ b/drivers/staging/iio/TODO
@@ -1,76 +1,8 @@
-2009 8/18
-
-Core:
-1) Get reviews
-2) Additional testing
-3) Ensure all desirable features present by adding more devices.
- Major changes not expected except in response to comments
-
-Max1363 core:
-1) Possibly add sysfs exports of constant useful to userspace.
-Would be nice
-2) Support hardware generated interrupts
-3) Expand device set. Lots of other maxim adc's have very
- similar interfaces.
-
-MXS LRADC driver:
-This is a classic MFD device as it combines the following subdevices
- - touchscreen controller (input subsystem related device)
- - general purpose ADC channels
- - battery voltage monitor (power subsystem related device)
- - die temperature monitor (thermal management)
-
-At least the battery voltage and die temperature feature is required in-kernel
-by a driver of the SoC's battery charging unit to avoid any damage to the
-silicon and the battery.
-
-TSL2561
-Would be nice
-1) Open question of userspace vs kernel space balance when
-converting to useful light measurements from device ones.
-2) Add sysfs elements necessary to allow device agnostic
-unit conversion.
-
-LIS3L02DQ core
-
-LIS3L02DQ ring
-
-KXSD9
-Currently minimal driver, would be nice to add:
-1) Support for all chip generated interrupts (events),
-basically get support up to level of lis3l02dq driver.
-
-Ring buffer core
-
-SCA3000
-Would be nice
-1) Testing on devices other than sca3000-e05
-
-Trigger core support
-1) Discussion of approach. Is it general enough?
-
-Ring Buffer:
-1) Discussion of approach.
-There are probably better ways of doing this. The
-intention is to allow for more than one software ring
-buffer implementation as different users will have
-different requirements. This one suits mid range
-frequencies (100Hz - 4kHz).
-2) Lots of testing
-
-GPIO trigger
-1) Add control over the type of interrupt etc. This will
-necessitate a header that is also visible from arch board
-files. (avoided at the moment to keep the driver set
-contained in staging).
+2016 10/09
ADI Drivers:
CC the device-drivers-devel@blackfin.uclinux.org mailing list when
e-mailing the normal IIO list (see below).
-Documentation
-1) Lots of cleanup and expansion.
-2) Some device require individual docs.
-
Contact: Jonathan Cameron <jic23@kernel.org>.
Mailing list: linux-iio@vger.kernel.org
diff --git a/drivers/staging/iio/accel/Kconfig b/drivers/staging/iio/accel/Kconfig
index 1c994b57c7d2..c6b0f5eae7ab 100644
--- a/drivers/staging/iio/accel/Kconfig
+++ b/drivers/staging/iio/accel/Kconfig
@@ -51,14 +51,4 @@ config ADIS16240
To compile this driver as a module, say M here: the module will be
called adis16240.
-config SCA3000
- depends on IIO_BUFFER
- depends on SPI
- tristate "VTI SCA3000 series accelerometers"
- help
- Say Y here to build support for the VTI SCA3000 series of SPI
- accelerometers. These devices use a hardware ring buffer.
-
- To compile this driver as a module, say M here: the module will be
- called sca3000.
endmenu
diff --git a/drivers/staging/iio/accel/Makefile b/drivers/staging/iio/accel/Makefile
index 1810a434a755..febb137b60c4 100644
--- a/drivers/staging/iio/accel/Makefile
+++ b/drivers/staging/iio/accel/Makefile
@@ -13,6 +13,3 @@ obj-$(CONFIG_ADIS16209) += adis16209.o
adis16240-y := adis16240_core.o
obj-$(CONFIG_ADIS16240) += adis16240.o
-
-sca3000-y := sca3000_core.o sca3000_ring.o
-obj-$(CONFIG_SCA3000) += sca3000.o
diff --git a/drivers/staging/iio/accel/sca3000.h b/drivers/staging/iio/accel/sca3000.h
deleted file mode 100644
index 4dcc8575cbe3..000000000000
--- a/drivers/staging/iio/accel/sca3000.h
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * sca3000.c -- support VTI sca3000 series accelerometers
- * via SPI
- *
- * Copyright (c) 2007 Jonathan Cameron <jic23@kernel.org>
- *
- * Partly based upon tle62x0.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Initial mode is direct measurement.
- *
- * Untested things
- *
- * Temperature reading (the e05 I'm testing with doesn't have a sensor)
- *
- * Free fall detection mode - supported but untested as I'm not droping my
- * dubious wire rig far enough to test it.
- *
- * Unsupported as yet
- *
- * Time stamping of data from ring. Various ideas on how to do this but none
- * are remotely simple. Suggestions welcome.
- *
- * Individual enabling disabling of channels going into ring buffer
- *
- * Overflow handling (this is signaled for all but 8 bit ring buffer mode.)
- *
- * Motion detector using AND combinations of signals.
- *
- * Note: Be very careful about not touching an register bytes marked
- * as reserved on the data sheet. They really mean it as changing convents of
- * some will cause the device to lock up.
- *
- * Known issues - on rare occasions the interrupts lock up. Not sure why as yet.
- * Can probably alleviate this by reading the interrupt register on start, but
- * that is really just brushing the problem under the carpet.
- */
-#ifndef _SCA3000
-#define _SCA3000
-
-#define SCA3000_WRITE_REG(a) (((a) << 2) | 0x02)
-#define SCA3000_READ_REG(a) ((a) << 2)
-
-#define SCA3000_REG_ADDR_REVID 0x00
-#define SCA3000_REVID_MAJOR_MASK 0xf0
-#define SCA3000_REVID_MINOR_MASK 0x0f
-
-#define SCA3000_REG_ADDR_STATUS 0x02
-#define SCA3000_LOCKED 0x20
-#define SCA3000_EEPROM_CS_ERROR 0x02
-#define SCA3000_SPI_FRAME_ERROR 0x01
-
-/* All reads done using register decrement so no need to directly access LSBs */
-#define SCA3000_REG_ADDR_X_MSB 0x05
-#define SCA3000_REG_ADDR_Y_MSB 0x07
-#define SCA3000_REG_ADDR_Z_MSB 0x09
-
-#define SCA3000_REG_ADDR_RING_OUT 0x0f
-
-/* Temp read untested - the e05 doesn't have the sensor */
-#define SCA3000_REG_ADDR_TEMP_MSB 0x13
-
-#define SCA3000_REG_ADDR_MODE 0x14
-#define SCA3000_MODE_PROT_MASK 0x28
-
-#define SCA3000_RING_BUF_ENABLE 0x80
-#define SCA3000_RING_BUF_8BIT 0x40
-/*
- * Free fall detection triggers an interrupt if the acceleration
- * is below a threshold for equivalent of 25cm drop
- */
-#define SCA3000_FREE_FALL_DETECT 0x10
-#define SCA3000_MEAS_MODE_NORMAL 0x00
-#define SCA3000_MEAS_MODE_OP_1 0x01
-#define SCA3000_MEAS_MODE_OP_2 0x02
-
-/*
- * In motion detection mode the accelerations are band pass filtered
- * (approx 1 - 25Hz) and then a programmable threshold used to trigger
- * and interrupt.
- */
-#define SCA3000_MEAS_MODE_MOT_DET 0x03
-
-#define SCA3000_REG_ADDR_BUF_COUNT 0x15
-
-#define SCA3000_REG_ADDR_INT_STATUS 0x16
-
-#define SCA3000_INT_STATUS_THREE_QUARTERS 0x80
-#define SCA3000_INT_STATUS_HALF 0x40
-
-#define SCA3000_INT_STATUS_FREE_FALL 0x08
-#define SCA3000_INT_STATUS_Y_TRIGGER 0x04
-#define SCA3000_INT_STATUS_X_TRIGGER 0x02
-#define SCA3000_INT_STATUS_Z_TRIGGER 0x01
-
-/* Used to allow access to multiplexed registers */
-#define SCA3000_REG_ADDR_CTRL_SEL 0x18
-/* Only available for SCA3000-D03 and SCA3000-D01 */
-#define SCA3000_REG_CTRL_SEL_I2C_DISABLE 0x01
-#define SCA3000_REG_CTRL_SEL_MD_CTRL 0x02
-#define SCA3000_REG_CTRL_SEL_MD_Y_TH 0x03
-#define SCA3000_REG_CTRL_SEL_MD_X_TH 0x04
-#define SCA3000_REG_CTRL_SEL_MD_Z_TH 0x05
-/*
- * BE VERY CAREFUL WITH THIS, IF 3 BITS ARE NOT SET the device
- * will not function
- */
-#define SCA3000_REG_CTRL_SEL_OUT_CTRL 0x0B
-#define SCA3000_OUT_CTRL_PROT_MASK 0xE0
-#define SCA3000_OUT_CTRL_BUF_X_EN 0x10
-#define SCA3000_OUT_CTRL_BUF_Y_EN 0x08
-#define SCA3000_OUT_CTRL_BUF_Z_EN 0x04
-#define SCA3000_OUT_CTRL_BUF_DIV_MASK 0x03
-#define SCA3000_OUT_CTRL_BUF_DIV_4 0x02
-#define SCA3000_OUT_CTRL_BUF_DIV_2 0x01
-
-/*
- * Control which motion detector interrupts are on.
- * For now only OR combinations are supported.
- */
-#define SCA3000_MD_CTRL_PROT_MASK 0xC0
-#define SCA3000_MD_CTRL_OR_Y 0x01
-#define SCA3000_MD_CTRL_OR_X 0x02
-#define SCA3000_MD_CTRL_OR_Z 0x04
-/* Currently unsupported */
-#define SCA3000_MD_CTRL_AND_Y 0x08
-#define SCA3000_MD_CTRL_AND_X 0x10
-#define SAC3000_MD_CTRL_AND_Z 0x20
-
-/*
- * Some control registers of complex access methods requiring this register to
- * be used to remove a lock.
- */
-#define SCA3000_REG_ADDR_UNLOCK 0x1e
-
-#define SCA3000_REG_ADDR_INT_MASK 0x21
-#define SCA3000_INT_MASK_PROT_MASK 0x1C
-
-#define SCA3000_INT_MASK_RING_THREE_QUARTER 0x80
-#define SCA3000_INT_MASK_RING_HALF 0x40
-
-#define SCA3000_INT_MASK_ALL_INTS 0x02
-#define SCA3000_INT_MASK_ACTIVE_HIGH 0x01
-#define SCA3000_INT_MASK_ACTIVE_LOW 0x00
-
-/* Values of multiplexed registers (write to ctrl_data after select) */
-#define SCA3000_REG_ADDR_CTRL_DATA 0x22
-
-/*
- * Measurement modes available on some sca3000 series chips. Code assumes others
- * may become available in the future.
- *
- * Bypass - Bypass the low-pass filter in the signal channel so as to increase
- * signal bandwidth.
- *
- * Narrow - Narrow low-pass filtering of the signal channel and half output
- * data rate by decimation.
- *
- * Wide - Widen low-pass filtering of signal channel to increase bandwidth
- */
-#define SCA3000_OP_MODE_BYPASS 0x01
-#define SCA3000_OP_MODE_NARROW 0x02
-#define SCA3000_OP_MODE_WIDE 0x04
-#define SCA3000_MAX_TX 6
-#define SCA3000_MAX_RX 2
-
-/**
- * struct sca3000_state - device instance state information
- * @us: the associated spi device
- * @info: chip variant information
- * @interrupt_handler_ws: event interrupt handler for all events
- * @last_timestamp: the timestamp of the last event
- * @mo_det_use_count: reference counter for the motion detection unit
- * @lock: lock used to protect elements of sca3000_state
- * and the underlying device state.
- * @bpse: number of bits per scan element
- * @tx: dma-able transmit buffer
- * @rx: dma-able receive buffer
- **/
-struct sca3000_state {
- struct spi_device *us;
- const struct sca3000_chip_info *info;
- struct work_struct interrupt_handler_ws;
- s64 last_timestamp;
- int mo_det_use_count;
- struct mutex lock;
- int bpse;
- /* Can these share a cacheline ? */
- u8 rx[2] ____cacheline_aligned;
- u8 tx[6] ____cacheline_aligned;
-};
-
-/**
- * struct sca3000_chip_info - model dependent parameters
- * @scale: scale * 10^-6
- * @temp_output: some devices have temperature sensors.
- * @measurement_mode_freq: normal mode sampling frequency
- * @option_mode_1: first optional mode. Not all models have one
- * @option_mode_1_freq: option mode 1 sampling frequency
- * @option_mode_2: second optional mode. Not all chips have one
- * @option_mode_2_freq: option mode 2 sampling frequency
- *
- * This structure is used to hold information about the functionality of a given
- * sca3000 variant.
- **/
-struct sca3000_chip_info {
- unsigned int scale;
- bool temp_output;
- int measurement_mode_freq;
- int option_mode_1;
- int option_mode_1_freq;
- int option_mode_2;
- int option_mode_2_freq;
- int mot_det_mult_xz[6];
- int mot_det_mult_y[7];
-};
-
-int sca3000_read_data_short(struct sca3000_state *st,
- u8 reg_address_high,
- int len);
-
-/**
- * sca3000_write_reg() write a single register
- * @address: address of register on chip
- * @val: value to be written to register
- *
- * The main lock must be held.
- **/
-int sca3000_write_reg(struct sca3000_state *st, u8 address, u8 val);
-
-#ifdef CONFIG_IIO_BUFFER
-/**
- * sca3000_register_ring_funcs() setup the ring state change functions
- **/
-void sca3000_register_ring_funcs(struct iio_dev *indio_dev);
-
-/**
- * sca3000_configure_ring() - allocate and configure ring buffer
- * @indio_dev: iio-core device whose ring is to be configured
- *
- * The hardware ring buffer needs far fewer ring buffer functions than
- * a software one as a lot of things are handled automatically.
- * This function also tells the iio core that our device supports a
- * hardware ring buffer mode.
- **/
-int sca3000_configure_ring(struct iio_dev *indio_dev);
-
-/**
- * sca3000_unconfigure_ring() - deallocate the ring buffer
- * @indio_dev: iio-core device whose ring we are freeing
- **/
-void sca3000_unconfigure_ring(struct iio_dev *indio_dev);
-
-/**
- * sca3000_ring_int_process() handles ring related event pushing and escalation
- * @val: the event code
- **/
-void sca3000_ring_int_process(u8 val, struct iio_buffer *ring);
-
-#else
-static inline void sca3000_register_ring_funcs(struct iio_dev *indio_dev)
-{
-}
-
-static inline
-int sca3000_register_ring_access_and_init(struct iio_dev *indio_dev)
-{
- return 0;
-}
-
-static inline void sca3000_ring_int_process(u8 val, void *ring)
-{
-}
-
-#endif
-#endif /* _SCA3000 */
diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c
deleted file mode 100644
index 564b36d4f648..000000000000
--- a/drivers/staging/iio/accel/sca3000_core.c
+++ /dev/null
@@ -1,1210 +0,0 @@
-/*
- * sca3000_core.c -- support VTI sca3000 series accelerometers via SPI
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * Copyright (c) 2009 Jonathan Cameron <jic23@kernel.org>
- *
- * See industrialio/accels/sca3000.h for comments.
- */
-
-#include <linux/interrupt.h>
-#include <linux/fs.h>
-#include <linux/device.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/sysfs.h>
-#include <linux/module.h>
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-#include <linux/iio/events.h>
-#include <linux/iio/buffer.h>
-
-#include "sca3000.h"
-
-enum sca3000_variant {
- d01,
- e02,
- e04,
- e05,
-};
-
-/*
- * Note where option modes are not defined, the chip simply does not
- * support any.
- * Other chips in the sca3000 series use i2c and are not included here.
- *
- * Some of these devices are only listed in the family data sheet and
- * do not actually appear to be available.
- */
-static const struct sca3000_chip_info sca3000_spi_chip_info_tbl[] = {
- [d01] = {
- .scale = 7357,
- .temp_output = true,
- .measurement_mode_freq = 250,
- .option_mode_1 = SCA3000_OP_MODE_BYPASS,
- .option_mode_1_freq = 250,
- .mot_det_mult_xz = {50, 100, 200, 350, 650, 1300},
- .mot_det_mult_y = {50, 100, 150, 250, 450, 850, 1750},
- },
- [e02] = {
- .scale = 9810,
- .measurement_mode_freq = 125,
- .option_mode_1 = SCA3000_OP_MODE_NARROW,
- .option_mode_1_freq = 63,
- .mot_det_mult_xz = {100, 150, 300, 550, 1050, 2050},
- .mot_det_mult_y = {50, 100, 200, 350, 700, 1350, 2700},
- },
- [e04] = {
- .scale = 19620,
- .measurement_mode_freq = 100,
- .option_mode_1 = SCA3000_OP_MODE_NARROW,
- .option_mode_1_freq = 50,
- .option_mode_2 = SCA3000_OP_MODE_WIDE,
- .option_mode_2_freq = 400,
- .mot_det_mult_xz = {200, 300, 600, 1100, 2100, 4100},
- .mot_det_mult_y = {100, 200, 400, 7000, 1400, 2700, 54000},
- },
- [e05] = {
- .scale = 61313,
- .measurement_mode_freq = 200,
- .option_mode_1 = SCA3000_OP_MODE_NARROW,
- .option_mode_1_freq = 50,
- .option_mode_2 = SCA3000_OP_MODE_WIDE,
- .option_mode_2_freq = 400,
- .mot_det_mult_xz = {600, 900, 1700, 3200, 6100, 11900},
- .mot_det_mult_y = {300, 600, 1200, 2000, 4100, 7800, 15600},
- },
-};
-
-int sca3000_write_reg(struct sca3000_state *st, u8 address, u8 val)
-{
- st->tx[0] = SCA3000_WRITE_REG(address);
- st->tx[1] = val;
- return spi_write(st->us, st->tx, 2);
-}
-
-int sca3000_read_data_short(struct sca3000_state *st,
- u8 reg_address_high,
- int len)
-{
- struct spi_transfer xfer[2] = {
- {
- .len = 1,
- .tx_buf = st->tx,
- }, {
- .len = len,
- .rx_buf = st->rx,
- }
- };
- st->tx[0] = SCA3000_READ_REG(reg_address_high);
-
- return spi_sync_transfer(st->us, xfer, ARRAY_SIZE(xfer));
-}
-
-/**
- * sca3000_reg_lock_on() test if the ctrl register lock is on
- *
- * Lock must be held.
- **/
-static int sca3000_reg_lock_on(struct sca3000_state *st)
-{
- int ret;
-
- ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_STATUS, 1);
- if (ret < 0)
- return ret;
-
- return !(st->rx[0] & SCA3000_LOCKED);
-}
-
-/**
- * __sca3000_unlock_reg_lock() unlock the control registers
- *
- * Note the device does not appear to support doing this in a single transfer.
- * This should only ever be used as part of ctrl reg read.
- * Lock must be held before calling this
- **/
-static int __sca3000_unlock_reg_lock(struct sca3000_state *st)
-{
- struct spi_transfer xfer[3] = {
- {
- .len = 2,
- .cs_change = 1,
- .tx_buf = st->tx,
- }, {
- .len = 2,
- .cs_change = 1,
- .tx_buf = st->tx + 2,
- }, {
- .len = 2,
- .tx_buf = st->tx + 4,
- },
- };
- st->tx[0] = SCA3000_WRITE_REG(SCA3000_REG_ADDR_UNLOCK);
- st->tx[1] = 0x00;
- st->tx[2] = SCA3000_WRITE_REG(SCA3000_REG_ADDR_UNLOCK);
- st->tx[3] = 0x50;
- st->tx[4] = SCA3000_WRITE_REG(SCA3000_REG_ADDR_UNLOCK);
- st->tx[5] = 0xA0;
-
- return spi_sync_transfer(st->us, xfer, ARRAY_SIZE(xfer));
-}
-
-/**
- * sca3000_write_ctrl_reg() write to a lock protect ctrl register
- * @sel: selects which registers we wish to write to
- * @val: the value to be written
- *
- * Certain control registers are protected against overwriting by the lock
- * register and use a shared write address. This function allows writing of
- * these registers.
- * Lock must be held.
- **/
-static int sca3000_write_ctrl_reg(struct sca3000_state *st,
- u8 sel,
- uint8_t val)
-{
- int ret;
-
- ret = sca3000_reg_lock_on(st);
- if (ret < 0)
- goto error_ret;
- if (ret) {
- ret = __sca3000_unlock_reg_lock(st);
- if (ret)
- goto error_ret;
- }
-
- /* Set the control select register */
- ret = sca3000_write_reg(st, SCA3000_REG_ADDR_CTRL_SEL, sel);
- if (ret)
- goto error_ret;
-
- /* Write the actual value into the register */
- ret = sca3000_write_reg(st, SCA3000_REG_ADDR_CTRL_DATA, val);
-
-error_ret:
- return ret;
-}
-
-/**
- * sca3000_read_ctrl_reg() read from lock protected control register.
- *
- * Lock must be held.
- **/
-static int sca3000_read_ctrl_reg(struct sca3000_state *st,
- u8 ctrl_reg)
-{
- int ret;
-
- ret = sca3000_reg_lock_on(st);
- if (ret < 0)
- goto error_ret;
- if (ret) {
- ret = __sca3000_unlock_reg_lock(st);
- if (ret)
- goto error_ret;
- }
- /* Set the control select register */
- ret = sca3000_write_reg(st, SCA3000_REG_ADDR_CTRL_SEL, ctrl_reg);
- if (ret)
- goto error_ret;
- ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_CTRL_DATA, 1);
- if (ret)
- goto error_ret;
- return st->rx[0];
-error_ret:
- return ret;
-}
-
-/**
- * sca3000_show_rev() - sysfs interface to read the chip revision number
- **/
-static ssize_t sca3000_show_rev(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- int len = 0, ret;
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct sca3000_state *st = iio_priv(indio_dev);
-
- mutex_lock(&st->lock);
- ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_REVID, 1);
- if (ret < 0)
- goto error_ret;
- len += sprintf(buf + len,
- "major=%d, minor=%d\n",
- st->rx[0] & SCA3000_REVID_MAJOR_MASK,
- st->rx[0] & SCA3000_REVID_MINOR_MASK);
-error_ret:
- mutex_unlock(&st->lock);
-
- return ret ? ret : len;
-}
-
-/**
- * sca3000_show_available_measurement_modes() display available modes
- *
- * This is all read from chip specific data in the driver. Not all
- * of the sca3000 series support modes other than normal.
- **/
-static ssize_t
-sca3000_show_available_measurement_modes(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct sca3000_state *st = iio_priv(indio_dev);
- int len = 0;
-
- len += sprintf(buf + len, "0 - normal mode");
- switch (st->info->option_mode_1) {
- case SCA3000_OP_MODE_NARROW:
- len += sprintf(buf + len, ", 1 - narrow mode");
- break;
- case SCA3000_OP_MODE_BYPASS:
- len += sprintf(buf + len, ", 1 - bypass mode");
- break;
- }
- switch (st->info->option_mode_2) {
- case SCA3000_OP_MODE_WIDE:
- len += sprintf(buf + len, ", 2 - wide mode");
- break;
- }
- /* always supported */
- len += sprintf(buf + len, " 3 - motion detection\n");
-
- return len;
-}
-
-/**
- * sca3000_show_measurement_mode() sysfs read of current mode
- **/
-static ssize_t
-sca3000_show_measurement_mode(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct sca3000_state *st = iio_priv(indio_dev);
- int len = 0, ret;
-
- mutex_lock(&st->lock);
- ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
- if (ret)
- goto error_ret;
- /* mask bottom 2 bits - only ones that are relevant */
- st->rx[0] &= 0x03;
- switch (st->rx[0]) {
- case SCA3000_MEAS_MODE_NORMAL:
- len += sprintf(buf + len, "0 - normal mode\n");
- break;
- case SCA3000_MEAS_MODE_MOT_DET:
- len += sprintf(buf + len, "3 - motion detection\n");
- break;
- case SCA3000_MEAS_MODE_OP_1:
- switch (st->info->option_mode_1) {
- case SCA3000_OP_MODE_NARROW:
- len += sprintf(buf + len, "1 - narrow mode\n");
- break;
- case SCA3000_OP_MODE_BYPASS:
- len += sprintf(buf + len, "1 - bypass mode\n");
- break;
- }
- break;
- case SCA3000_MEAS_MODE_OP_2:
- switch (st->info->option_mode_2) {
- case SCA3000_OP_MODE_WIDE:
- len += sprintf(buf + len, "2 - wide mode\n");
- break;
- }
- break;
- }
-
-error_ret:
- mutex_unlock(&st->lock);
-
- return ret ? ret : len;
-}
-
-/**
- * sca3000_store_measurement_mode() set the current mode
- **/
-static ssize_t
-sca3000_store_measurement_mode(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct sca3000_state *st = iio_priv(indio_dev);
- int ret;
- u8 mask = 0x03;
- u8 val;
-
- mutex_lock(&st->lock);
- ret = kstrtou8(buf, 10, &val);
- if (ret)
- goto error_ret;
- if (val > 3) {
- ret = -EINVAL;
- goto error_ret;
- }
- ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
- if (ret)
- goto error_ret;
- st->rx[0] &= ~mask;
- st->rx[0] |= (val & mask);
- ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE, st->rx[0]);
- if (ret)
- goto error_ret;
- mutex_unlock(&st->lock);
-
- return len;
-
-error_ret:
- mutex_unlock(&st->lock);
-
- return ret;
-}
-
-/*
- * Not even vaguely standard attributes so defined here rather than
- * in the relevant IIO core headers
- */
-static IIO_DEVICE_ATTR(measurement_mode_available, S_IRUGO,
- sca3000_show_available_measurement_modes,
- NULL, 0);
-
-static IIO_DEVICE_ATTR(measurement_mode, S_IRUGO | S_IWUSR,
- sca3000_show_measurement_mode,
- sca3000_store_measurement_mode,
- 0);
-
-/* More standard attributes */
-
-static IIO_DEVICE_ATTR(revision, S_IRUGO, sca3000_show_rev, NULL, 0);
-
-static const struct iio_event_spec sca3000_event = {
- .type = IIO_EV_TYPE_MAG,
- .dir = IIO_EV_DIR_RISING,
- .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
-};
-
-#define SCA3000_CHAN(index, mod) \
- { \
- .type = IIO_ACCEL, \
- .modified = 1, \
- .channel2 = mod, \
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
- .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),\
- .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),\
- .address = index, \
- .scan_index = index, \
- .scan_type = { \
- .sign = 's', \
- .realbits = 11, \
- .storagebits = 16, \
- .shift = 5, \
- }, \
- .event_spec = &sca3000_event, \
- .num_event_specs = 1, \
- }
-
-static const struct iio_chan_spec sca3000_channels[] = {
- SCA3000_CHAN(0, IIO_MOD_X),
- SCA3000_CHAN(1, IIO_MOD_Y),
- SCA3000_CHAN(2, IIO_MOD_Z),
-};
-
-static const struct iio_chan_spec sca3000_channels_with_temp[] = {
- SCA3000_CHAN(0, IIO_MOD_X),
- SCA3000_CHAN(1, IIO_MOD_Y),
- SCA3000_CHAN(2, IIO_MOD_Z),
- {
- .type = IIO_TEMP,
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
- .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |
- BIT(IIO_CHAN_INFO_OFFSET),
- /* No buffer support */
- .scan_index = -1,
- },
-};
-
-static u8 sca3000_addresses[3][3] = {
- [0] = {SCA3000_REG_ADDR_X_MSB, SCA3000_REG_CTRL_SEL_MD_X_TH,
- SCA3000_MD_CTRL_OR_X},
- [1] = {SCA3000_REG_ADDR_Y_MSB, SCA3000_REG_CTRL_SEL_MD_Y_TH,
- SCA3000_MD_CTRL_OR_Y},
- [2] = {SCA3000_REG_ADDR_Z_MSB, SCA3000_REG_CTRL_SEL_MD_Z_TH,
- SCA3000_MD_CTRL_OR_Z},
-};
-
-/**
- * __sca3000_get_base_freq() obtain mode specific base frequency
- *
- * lock must be held
- **/
-static inline int __sca3000_get_base_freq(struct sca3000_state *st,
- const struct sca3000_chip_info *info,
- int *base_freq)
-{
- int ret;
-
- ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
- if (ret)
- goto error_ret;
- switch (0x03 & st->rx[0]) {
- case SCA3000_MEAS_MODE_NORMAL:
- *base_freq = info->measurement_mode_freq;
- break;
- case SCA3000_MEAS_MODE_OP_1:
- *base_freq = info->option_mode_1_freq;
- break;
- case SCA3000_MEAS_MODE_OP_2:
- *base_freq = info->option_mode_2_freq;
- break;
- default:
- ret = -EINVAL;
- }
-error_ret:
- return ret;
-}
-
-/**
- * read_raw handler for IIO_CHAN_INFO_SAMP_FREQ
- *
- * lock must be held
- **/
-static int read_raw_samp_freq(struct sca3000_state *st, int *val)
-{
- int ret;
-
- ret = __sca3000_get_base_freq(st, st->info, val);
- if (ret)
- return ret;
-
- ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL);
- if (ret < 0)
- return ret;
-
- if (*val > 0) {
- ret &= SCA3000_OUT_CTRL_BUF_DIV_MASK;
- switch (ret) {
- case SCA3000_OUT_CTRL_BUF_DIV_2:
- *val /= 2;
- break;
- case SCA3000_OUT_CTRL_BUF_DIV_4:
- *val /= 4;
- break;
- }
- }
-
- return 0;
-}
-
-/**
- * write_raw handler for IIO_CHAN_INFO_SAMP_FREQ
- *
- * lock must be held
- **/
-static int write_raw_samp_freq(struct sca3000_state *st, int val)
-{
- int ret, base_freq, ctrlval;
-
- ret = __sca3000_get_base_freq(st, st->info, &base_freq);
- if (ret)
- return ret;
-
- ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL);
- if (ret < 0)
- return ret;
-
- ctrlval = ret & ~SCA3000_OUT_CTRL_BUF_DIV_MASK;
-
- if (val == base_freq / 2)
- ctrlval |= SCA3000_OUT_CTRL_BUF_DIV_2;
- if (val == base_freq / 4)
- ctrlval |= SCA3000_OUT_CTRL_BUF_DIV_4;
- else if (val != base_freq)
- return -EINVAL;
-
- return sca3000_write_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL,
- ctrlval);
-}
-
-static int sca3000_read_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int *val,
- int *val2,
- long mask)
-{
- struct sca3000_state *st = iio_priv(indio_dev);
- int ret;
- u8 address;
-
- switch (mask) {
- case IIO_CHAN_INFO_RAW:
- mutex_lock(&st->lock);
- if (chan->type == IIO_ACCEL) {
- if (st->mo_det_use_count) {
- mutex_unlock(&st->lock);
- return -EBUSY;
- }
- address = sca3000_addresses[chan->address][0];
- ret = sca3000_read_data_short(st, address, 2);
- if (ret < 0) {
- mutex_unlock(&st->lock);
- return ret;
- }
- *val = (be16_to_cpup((__be16 *)st->rx) >> 3) & 0x1FFF;
- *val = ((*val) << (sizeof(*val) * 8 - 13)) >>
- (sizeof(*val) * 8 - 13);
- } else {
- /* get the temperature when available */
- ret = sca3000_read_data_short(st,
- SCA3000_REG_ADDR_TEMP_MSB,
- 2);
- if (ret < 0) {
- mutex_unlock(&st->lock);
- return ret;
- }
- *val = ((st->rx[0] & 0x3F) << 3) |
- ((st->rx[1] & 0xE0) >> 5);
- }
- mutex_unlock(&st->lock);
- return IIO_VAL_INT;
- case IIO_CHAN_INFO_SCALE:
- *val = 0;
- if (chan->type == IIO_ACCEL)
- *val2 = st->info->scale;
- else /* temperature */
- *val2 = 555556;
- return IIO_VAL_INT_PLUS_MICRO;
- case IIO_CHAN_INFO_OFFSET:
- *val = -214;
- *val2 = 600000;
- return IIO_VAL_INT_PLUS_MICRO;
- case IIO_CHAN_INFO_SAMP_FREQ:
- mutex_lock(&st->lock);
- ret = read_raw_samp_freq(st, val);
- mutex_unlock(&st->lock);
- return ret ? ret : IIO_VAL_INT;
- default:
- return -EINVAL;
- }
-}
-
-static int sca3000_write_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int val, int val2, long mask)
-{
- struct sca3000_state *st = iio_priv(indio_dev);
- int ret;
-
- switch (mask) {
- case IIO_CHAN_INFO_SAMP_FREQ:
- if (val2)
- return -EINVAL;
- mutex_lock(&st->lock);
- ret = write_raw_samp_freq(st, val);
- mutex_unlock(&st->lock);
- return ret;
- default:
- return -EINVAL;
- }
-
- return ret;
-}
-
-/**
- * sca3000_read_av_freq() sysfs function to get available frequencies
- *
- * The later modes are only relevant to the ring buffer - and depend on current
- * mode. Note that data sheet gives rather wide tolerances for these so integer
- * division will give good enough answer and not all chips have them specified
- * at all.
- **/
-static ssize_t sca3000_read_av_freq(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct sca3000_state *st = iio_priv(indio_dev);
- int len = 0, ret, val;
-
- mutex_lock(&st->lock);
- ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
- val = st->rx[0];
- mutex_unlock(&st->lock);
- if (ret)
- goto error_ret;
-
- switch (val & 0x03) {
- case SCA3000_MEAS_MODE_NORMAL:
- len += sprintf(buf + len, "%d %d %d\n",
- st->info->measurement_mode_freq,
- st->info->measurement_mode_freq / 2,
- st->info->measurement_mode_freq / 4);
- break;
- case SCA3000_MEAS_MODE_OP_1:
- len += sprintf(buf + len, "%d %d %d\n",
- st->info->option_mode_1_freq,
- st->info->option_mode_1_freq / 2,
- st->info->option_mode_1_freq / 4);
- break;
- case SCA3000_MEAS_MODE_OP_2:
- len += sprintf(buf + len, "%d %d %d\n",
- st->info->option_mode_2_freq,
- st->info->option_mode_2_freq / 2,
- st->info->option_mode_2_freq / 4);
- break;
- }
- return len;
-error_ret:
- return ret;
-}
-
-/*
- * Should only really be registered if ring buffer support is compiled in.
- * Does no harm however and doing it right would add a fair bit of complexity
- */
-static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(sca3000_read_av_freq);
-
-/**
- * sca3000_read_thresh() - query of a threshold
- **/
-static int sca3000_read_thresh(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
- enum iio_event_info info,
- int *val, int *val2)
-{
- int ret, i;
- struct sca3000_state *st = iio_priv(indio_dev);
- int num = chan->channel2;
-
- mutex_lock(&st->lock);
- ret = sca3000_read_ctrl_reg(st, sca3000_addresses[num][1]);
- mutex_unlock(&st->lock);
- if (ret < 0)
- return ret;
- *val = 0;
- if (num == 1)
- for_each_set_bit(i, (unsigned long *)&ret,
- ARRAY_SIZE(st->info->mot_det_mult_y))
- *val += st->info->mot_det_mult_y[i];
- else
- for_each_set_bit(i, (unsigned long *)&ret,
- ARRAY_SIZE(st->info->mot_det_mult_xz))
- *val += st->info->mot_det_mult_xz[i];
-
- return IIO_VAL_INT;
-}
-
-/**
- * sca3000_write_thresh() control of threshold
- **/
-static int sca3000_write_thresh(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
- enum iio_event_info info,
- int val, int val2)
-{
- struct sca3000_state *st = iio_priv(indio_dev);
- int num = chan->channel2;
- int ret;
- int i;
- u8 nonlinear = 0;
-
- if (num == 1) {
- i = ARRAY_SIZE(st->info->mot_det_mult_y);
- while (i > 0)
- if (val >= st->info->mot_det_mult_y[--i]) {
- nonlinear |= (1 << i);
- val -= st->info->mot_det_mult_y[i];
- }
- } else {
- i = ARRAY_SIZE(st->info->mot_det_mult_xz);
- while (i > 0)
- if (val >= st->info->mot_det_mult_xz[--i]) {
- nonlinear |= (1 << i);
- val -= st->info->mot_det_mult_xz[i];
- }
- }
-
- mutex_lock(&st->lock);
- ret = sca3000_write_ctrl_reg(st, sca3000_addresses[num][1], nonlinear);
- mutex_unlock(&st->lock);
-
- return ret;
-}
-
-static struct attribute *sca3000_attributes[] = {
- &iio_dev_attr_revision.dev_attr.attr,
- &iio_dev_attr_measurement_mode_available.dev_attr.attr,
- &iio_dev_attr_measurement_mode.dev_attr.attr,
- &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
- NULL,
-};
-
-static const struct attribute_group sca3000_attribute_group = {
- .attrs = sca3000_attributes,
-};
-
-/**
- * sca3000_event_handler() - handling ring and non ring events
- *
- * Ring related interrupt handler. Depending on event, push to
- * the ring buffer event chrdev or the event one.
- *
- * This function is complicated by the fact that the devices can signify ring
- * and non ring events via the same interrupt line and they can only
- * be distinguished via a read of the relevant status register.
- **/
-static irqreturn_t sca3000_event_handler(int irq, void *private)
-{
- struct iio_dev *indio_dev = private;
- struct sca3000_state *st = iio_priv(indio_dev);
- int ret, val;
- s64 last_timestamp = iio_get_time_ns(indio_dev);
-
- /*
- * Could lead if badly timed to an extra read of status reg,
- * but ensures no interrupt is missed.
- */
- mutex_lock(&st->lock);
- ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_STATUS, 1);
- val = st->rx[0];
- mutex_unlock(&st->lock);
- if (ret)
- goto done;
-
- sca3000_ring_int_process(val, indio_dev->buffer);
-
- if (val & SCA3000_INT_STATUS_FREE_FALL)
- iio_push_event(indio_dev,
- IIO_MOD_EVENT_CODE(IIO_ACCEL,
- 0,
- IIO_MOD_X_AND_Y_AND_Z,
- IIO_EV_TYPE_MAG,
- IIO_EV_DIR_FALLING),
- last_timestamp);
-
- if (val & SCA3000_INT_STATUS_Y_TRIGGER)
- iio_push_event(indio_dev,
- IIO_MOD_EVENT_CODE(IIO_ACCEL,
- 0,
- IIO_MOD_Y,
- IIO_EV_TYPE_MAG,
- IIO_EV_DIR_RISING),
- last_timestamp);
-
- if (val & SCA3000_INT_STATUS_X_TRIGGER)
- iio_push_event(indio_dev,
- IIO_MOD_EVENT_CODE(IIO_ACCEL,
- 0,
- IIO_MOD_X,
- IIO_EV_TYPE_MAG,
- IIO_EV_DIR_RISING),
- last_timestamp);
-
- if (val & SCA3000_INT_STATUS_Z_TRIGGER)
- iio_push_event(indio_dev,
- IIO_MOD_EVENT_CODE(IIO_ACCEL,
- 0,
- IIO_MOD_Z,
- IIO_EV_TYPE_MAG,
- IIO_EV_DIR_RISING),
- last_timestamp);
-
-done:
- return IRQ_HANDLED;
-}
-
-/**
- * sca3000_read_event_config() what events are enabled
- **/
-static int sca3000_read_event_config(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir)
-{
- struct sca3000_state *st = iio_priv(indio_dev);
- int ret;
- u8 protect_mask = 0x03;
- int num = chan->channel2;
-
- /* read current value of mode register */
- mutex_lock(&st->lock);
- ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
- if (ret)
- goto error_ret;
-
- if ((st->rx[0] & protect_mask) != SCA3000_MEAS_MODE_MOT_DET) {
- ret = 0;
- } else {
- ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_MD_CTRL);
- if (ret < 0)
- goto error_ret;
- /* only supporting logical or's for now */
- ret = !!(ret & sca3000_addresses[num][2]);
- }
-error_ret:
- mutex_unlock(&st->lock);
-
- return ret;
-}
-
-/**
- * sca3000_query_free_fall_mode() is free fall mode enabled
- **/
-static ssize_t sca3000_query_free_fall_mode(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- int ret;
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct sca3000_state *st = iio_priv(indio_dev);
- int val;
-
- mutex_lock(&st->lock);
- ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
- val = st->rx[0];
- mutex_unlock(&st->lock);
- if (ret < 0)
- return ret;
- return sprintf(buf, "%d\n", !!(val & SCA3000_FREE_FALL_DETECT));
-}
-
-/**
- * sca3000_set_free_fall_mode() simple on off control for free fall int
- *
- * In these chips the free fall detector should send an interrupt if
- * the device falls more than 25cm. This has not been tested due
- * to fragile wiring.
- **/
-static ssize_t sca3000_set_free_fall_mode(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct sca3000_state *st = iio_priv(indio_dev);
- u8 val;
- int ret;
- u8 protect_mask = SCA3000_FREE_FALL_DETECT;
-
- mutex_lock(&st->lock);
- ret = kstrtou8(buf, 10, &val);
- if (ret)
- goto error_ret;
-
- /* read current value of mode register */
- ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
- if (ret)
- goto error_ret;
-
- /* if off and should be on */
- if (val && !(st->rx[0] & protect_mask))
- ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
- (st->rx[0] | SCA3000_FREE_FALL_DETECT));
- /* if on and should be off */
- else if (!val && (st->rx[0] & protect_mask))
- ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
- (st->rx[0] & ~protect_mask));
-error_ret:
- mutex_unlock(&st->lock);
-
- return ret ? ret : len;
-}
-
-/**
- * sca3000_write_event_config() simple on off control for motion detector
- *
- * This is a per axis control, but enabling any will result in the
- * motion detector unit being enabled.
- * N.B. enabling motion detector stops normal data acquisition.
- * There is a complexity in knowing which mode to return to when
- * this mode is disabled. Currently normal mode is assumed.
- **/
-static int sca3000_write_event_config(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
- int state)
-{
- struct sca3000_state *st = iio_priv(indio_dev);
- int ret, ctrlval;
- u8 protect_mask = 0x03;
- int num = chan->channel2;
-
- mutex_lock(&st->lock);
- /*
- * First read the motion detector config to find out if
- * this axis is on
- */
- ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_MD_CTRL);
- if (ret < 0)
- goto exit_point;
- ctrlval = ret;
- /* if off and should be on */
- if (state && !(ctrlval & sca3000_addresses[num][2])) {
- ret = sca3000_write_ctrl_reg(st,
- SCA3000_REG_CTRL_SEL_MD_CTRL,
- ctrlval |
- sca3000_addresses[num][2]);
- if (ret)
- goto exit_point;
- st->mo_det_use_count++;
- } else if (!state && (ctrlval & sca3000_addresses[num][2])) {
- ret = sca3000_write_ctrl_reg(st,
- SCA3000_REG_CTRL_SEL_MD_CTRL,
- ctrlval &
- ~(sca3000_addresses[num][2]));
- if (ret)
- goto exit_point;
- st->mo_det_use_count--;
- }
-
- /* read current value of mode register */
- ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
- if (ret)
- goto exit_point;
- /* if off and should be on */
- if ((st->mo_det_use_count) &&
- ((st->rx[0] & protect_mask) != SCA3000_MEAS_MODE_MOT_DET))
- ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
- (st->rx[0] & ~protect_mask)
- | SCA3000_MEAS_MODE_MOT_DET);
- /* if on and should be off */
- else if (!(st->mo_det_use_count) &&
- ((st->rx[0] & protect_mask) == SCA3000_MEAS_MODE_MOT_DET))
- ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
- (st->rx[0] & ~protect_mask));
-exit_point:
- mutex_unlock(&st->lock);
-
- return ret;
-}
-
-/* Free fall detector related event attribute */
-static IIO_DEVICE_ATTR_NAMED(accel_xayaz_mag_falling_en,
- in_accel_x & y & z_mag_falling_en,
- S_IRUGO | S_IWUSR,
- sca3000_query_free_fall_mode,
- sca3000_set_free_fall_mode,
- 0);
-
-static IIO_CONST_ATTR_NAMED(accel_xayaz_mag_falling_period,
- in_accel_x & y & z_mag_falling_period,
- "0.226");
-
-static struct attribute *sca3000_event_attributes[] = {
- &iio_dev_attr_accel_xayaz_mag_falling_en.dev_attr.attr,
- &iio_const_attr_accel_xayaz_mag_falling_period.dev_attr.attr,
- NULL,
-};
-
-static struct attribute_group sca3000_event_attribute_group = {
- .attrs = sca3000_event_attributes,
- .name = "events",
-};
-
-/**
- * sca3000_clean_setup() get the device into a predictable state
- *
- * Devices use flash memory to store many of the register values
- * and hence can come up in somewhat unpredictable states.
- * Hence reset everything on driver load.
- **/
-static int sca3000_clean_setup(struct sca3000_state *st)
-{
- int ret;
-
- mutex_lock(&st->lock);
- /* Ensure all interrupts have been acknowledged */
- ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_STATUS, 1);
- if (ret)
- goto error_ret;
-
- /* Turn off all motion detection channels */
- ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_MD_CTRL);
- if (ret < 0)
- goto error_ret;
- ret = sca3000_write_ctrl_reg(st, SCA3000_REG_CTRL_SEL_MD_CTRL,
- ret & SCA3000_MD_CTRL_PROT_MASK);
- if (ret)
- goto error_ret;
-
- /* Disable ring buffer */
- ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL);
- if (ret < 0)
- goto error_ret;
- ret = sca3000_write_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL,
- (ret & SCA3000_OUT_CTRL_PROT_MASK)
- | SCA3000_OUT_CTRL_BUF_X_EN
- | SCA3000_OUT_CTRL_BUF_Y_EN
- | SCA3000_OUT_CTRL_BUF_Z_EN
- | SCA3000_OUT_CTRL_BUF_DIV_4);
- if (ret)
- goto error_ret;
- /* Enable interrupts, relevant to mode and set up as active low */
- ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_MASK, 1);
- if (ret)
- goto error_ret;
- ret = sca3000_write_reg(st,
- SCA3000_REG_ADDR_INT_MASK,
- (ret & SCA3000_INT_MASK_PROT_MASK)
- | SCA3000_INT_MASK_ACTIVE_LOW);
- if (ret)
- goto error_ret;
- /*
- * Select normal measurement mode, free fall off, ring off
- * Ring in 12 bit mode - it is fine to overwrite reserved bits 3,5
- * as that occurs in one of the example on the datasheet
- */
- ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
- if (ret)
- goto error_ret;
- ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
- (st->rx[0] & SCA3000_MODE_PROT_MASK));
- st->bpse = 11;
-
-error_ret:
- mutex_unlock(&st->lock);
- return ret;
-}
-
-static const struct iio_info sca3000_info = {
- .attrs = &sca3000_attribute_group,
- .read_raw = &sca3000_read_raw,
- .write_raw = &sca3000_write_raw,
- .event_attrs = &sca3000_event_attribute_group,
- .read_event_value = &sca3000_read_thresh,
- .write_event_value = &sca3000_write_thresh,
- .read_event_config = &sca3000_read_event_config,
- .write_event_config = &sca3000_write_event_config,
- .driver_module = THIS_MODULE,
-};
-
-static int sca3000_probe(struct spi_device *spi)
-{
- int ret;
- struct sca3000_state *st;
- struct iio_dev *indio_dev;
-
- indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
- if (!indio_dev)
- return -ENOMEM;
-
- st = iio_priv(indio_dev);
- spi_set_drvdata(spi, indio_dev);
- st->us = spi;
- mutex_init(&st->lock);
- st->info = &sca3000_spi_chip_info_tbl[spi_get_device_id(spi)
- ->driver_data];
-
- indio_dev->dev.parent = &spi->dev;
- indio_dev->name = spi_get_device_id(spi)->name;
- indio_dev->info = &sca3000_info;
- if (st->info->temp_output) {
- indio_dev->channels = sca3000_channels_with_temp;
- indio_dev->num_channels =
- ARRAY_SIZE(sca3000_channels_with_temp);
- } else {
- indio_dev->channels = sca3000_channels;
- indio_dev->num_channels = ARRAY_SIZE(sca3000_channels);
- }
- indio_dev->modes = INDIO_DIRECT_MODE;
-
- sca3000_configure_ring(indio_dev);
- ret = iio_device_register(indio_dev);
- if (ret < 0)
- return ret;
-
- if (spi->irq) {
- ret = request_threaded_irq(spi->irq,
- NULL,
- &sca3000_event_handler,
- IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
- "sca3000",
- indio_dev);
- if (ret)
- goto error_unregister_dev;
- }
- sca3000_register_ring_funcs(indio_dev);
- ret = sca3000_clean_setup(st);
- if (ret)
- goto error_free_irq;
- return 0;
-
-error_free_irq:
- if (spi->irq)
- free_irq(spi->irq, indio_dev);
-error_unregister_dev:
- iio_device_unregister(indio_dev);
- return ret;
-}
-
-static int sca3000_stop_all_interrupts(struct sca3000_state *st)
-{
- int ret;
-
- mutex_lock(&st->lock);
- ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_MASK, 1);
- if (ret)
- goto error_ret;
- ret = sca3000_write_reg(st, SCA3000_REG_ADDR_INT_MASK,
- (st->rx[0] &
- ~(SCA3000_INT_MASK_RING_THREE_QUARTER |
- SCA3000_INT_MASK_RING_HALF |
- SCA3000_INT_MASK_ALL_INTS)));
-error_ret:
- mutex_unlock(&st->lock);
- return ret;
-}
-
-static int sca3000_remove(struct spi_device *spi)
-{
- struct iio_dev *indio_dev = spi_get_drvdata(spi);
- struct sca3000_state *st = iio_priv(indio_dev);
-
- /* Must ensure no interrupts can be generated after this! */
- sca3000_stop_all_interrupts(st);
- if (spi->irq)
- free_irq(spi->irq, indio_dev);
- iio_device_unregister(indio_dev);
- sca3000_unconfigure_ring(indio_dev);
-
- return 0;
-}
-
-static const struct spi_device_id sca3000_id[] = {
- {"sca3000_d01", d01},
- {"sca3000_e02", e02},
- {"sca3000_e04", e04},
- {"sca3000_e05", e05},
- {}
-};
-MODULE_DEVICE_TABLE(spi, sca3000_id);
-
-static struct spi_driver sca3000_driver = {
- .driver = {
- .name = "sca3000",
- },
- .probe = sca3000_probe,
- .remove = sca3000_remove,
- .id_table = sca3000_id,
-};
-module_spi_driver(sca3000_driver);
-
-MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
-MODULE_DESCRIPTION("VTI SCA3000 Series Accelerometers SPI driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c
deleted file mode 100644
index d1cb9b9cf22b..000000000000
--- a/drivers/staging/iio/accel/sca3000_ring.c
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- * sca3000_ring.c -- support VTI sca3000 series accelerometers via SPI
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * Copyright (c) 2009 Jonathan Cameron <jic23@kernel.org>
- *
- */
-
-#include <linux/interrupt.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/sysfs.h>
-#include <linux/sched.h>
-#include <linux/poll.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-#include <linux/iio/buffer.h>
-#include "../ring_hw.h"
-#include "sca3000.h"
-
-/* RFC / future work
- *
- * The internal ring buffer doesn't actually change what it holds depending
- * on which signals are enabled etc, merely whether you can read them.
- * As such the scan mode selection is somewhat different than for a software
- * ring buffer and changing it actually covers any data already in the buffer.
- * Currently scan elements aren't configured so it doesn't matter.
- */
-
-static int sca3000_read_data(struct sca3000_state *st,
- u8 reg_address_high,
- u8 **rx_p,
- int len)
-{
- int ret;
- struct spi_transfer xfer[2] = {
- {
- .len = 1,
- .tx_buf = st->tx,
- }, {
- .len = len,
- }
- };
- *rx_p = kmalloc(len, GFP_KERNEL);
- if (!*rx_p) {
- ret = -ENOMEM;
- goto error_ret;
- }
- xfer[1].rx_buf = *rx_p;
- st->tx[0] = SCA3000_READ_REG(reg_address_high);
- ret = spi_sync_transfer(st->us, xfer, ARRAY_SIZE(xfer));
- if (ret) {
- dev_err(get_device(&st->us->dev), "problem reading register");
- goto error_free_rx;
- }
-
- return 0;
-error_free_rx:
- kfree(*rx_p);
-error_ret:
- return ret;
-}
-
-/**
- * sca3000_read_first_n_hw_rb() - main ring access, pulls data from ring
- * @r: the ring
- * @count: number of samples to try and pull
- * @data: output the actual samples pulled from the hw ring
- *
- * Currently does not provide timestamps. As the hardware doesn't add them they
- * can only be inferred approximately from ring buffer events such as 50% full
- * and knowledge of when buffer was last emptied. This is left to userspace.
- **/
-static int sca3000_read_first_n_hw_rb(struct iio_buffer *r,
- size_t count, char __user *buf)
-{
- struct iio_hw_buffer *hw_ring = iio_to_hw_buf(r);
- struct iio_dev *indio_dev = hw_ring->private;
- struct sca3000_state *st = iio_priv(indio_dev);
- u8 *rx;
- int ret, i, num_available, num_read = 0;
- int bytes_per_sample = 1;
-
- if (st->bpse == 11)
- bytes_per_sample = 2;
-
- mutex_lock(&st->lock);
- if (count % bytes_per_sample) {
- ret = -EINVAL;
- goto error_ret;
- }
-
- ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_BUF_COUNT, 1);
- if (ret)
- goto error_ret;
- num_available = st->rx[0];
- /*
- * num_available is the total number of samples available
- * i.e. number of time points * number of channels.
- */
- if (count > num_available * bytes_per_sample)
- num_read = num_available * bytes_per_sample;
- else
- num_read = count;
-
- ret = sca3000_read_data(st,
- SCA3000_REG_ADDR_RING_OUT,
- &rx, num_read);
- if (ret)
- goto error_ret;
-
- for (i = 0; i < num_read / sizeof(u16); i++)
- *(((u16 *)rx) + i) = be16_to_cpup((__be16 *)rx + i);
-
- if (copy_to_user(buf, rx, num_read))
- ret = -EFAULT;
- kfree(rx);
- r->stufftoread = 0;
-error_ret:
- mutex_unlock(&st->lock);
-
- return ret ? ret : num_read;
-}
-
-static size_t sca3000_ring_buf_data_available(struct iio_buffer *r)
-{
- return r->stufftoread ? r->watermark : 0;
-}
-
-/**
- * sca3000_query_ring_int() is the hardware ring status interrupt enabled
- **/
-static ssize_t sca3000_query_ring_int(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
- int ret, val;
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct sca3000_state *st = iio_priv(indio_dev);
-
- mutex_lock(&st->lock);
- ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_MASK, 1);
- val = st->rx[0];
- mutex_unlock(&st->lock);
- if (ret)
- return ret;
-
- return sprintf(buf, "%d\n", !!(val & this_attr->address));
-}
-
-/**
- * sca3000_set_ring_int() set state of ring status interrupt
- **/
-static ssize_t sca3000_set_ring_int(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct sca3000_state *st = iio_priv(indio_dev);
- struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
- u8 val;
- int ret;
-
- mutex_lock(&st->lock);
- ret = kstrtou8(buf, 10, &val);
- if (ret)
- goto error_ret;
- ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_MASK, 1);
- if (ret)
- goto error_ret;
- if (val)
- ret = sca3000_write_reg(st,
- SCA3000_REG_ADDR_INT_MASK,
- st->rx[0] | this_attr->address);
- else
- ret = sca3000_write_reg(st,
- SCA3000_REG_ADDR_INT_MASK,
- st->rx[0] & ~this_attr->address);
-error_ret:
- mutex_unlock(&st->lock);
-
- return ret ? ret : len;
-}
-
-static IIO_DEVICE_ATTR(50_percent, S_IRUGO | S_IWUSR,
- sca3000_query_ring_int,
- sca3000_set_ring_int,
- SCA3000_INT_MASK_RING_HALF);
-
-static IIO_DEVICE_ATTR(75_percent, S_IRUGO | S_IWUSR,
- sca3000_query_ring_int,
- sca3000_set_ring_int,
- SCA3000_INT_MASK_RING_THREE_QUARTER);
-
-static ssize_t sca3000_show_buffer_scale(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct sca3000_state *st = iio_priv(indio_dev);
-
- return sprintf(buf, "0.%06d\n", 4 * st->info->scale);
-}
-
-static IIO_DEVICE_ATTR(in_accel_scale,
- S_IRUGO,
- sca3000_show_buffer_scale,
- NULL,
- 0);
-
-/*
- * Ring buffer attributes
- * This device is a bit unusual in that the sampling frequency and bpse
- * only apply to the ring buffer. At all times full rate and accuracy
- * is available via direct reading from registers.
- */
-static const struct attribute *sca3000_ring_attributes[] = {
- &iio_dev_attr_50_percent.dev_attr.attr,
- &iio_dev_attr_75_percent.dev_attr.attr,
- &iio_dev_attr_in_accel_scale.dev_attr.attr,
- NULL,
-};
-
-static struct iio_buffer *sca3000_rb_allocate(struct iio_dev *indio_dev)
-{
- struct iio_buffer *buf;
- struct iio_hw_buffer *ring;
-
- ring = kzalloc(sizeof(*ring), GFP_KERNEL);
- if (!ring)
- return NULL;
-
- ring->private = indio_dev;
- buf = &ring->buf;
- buf->stufftoread = 0;
- buf->length = 64;
- buf->attrs = sca3000_ring_attributes;
- iio_buffer_init(buf);
-
- return buf;
-}
-
-static void sca3000_ring_release(struct iio_buffer *r)
-{
- kfree(iio_to_hw_buf(r));
-}
-
-static const struct iio_buffer_access_funcs sca3000_ring_access_funcs = {
- .read_first_n = &sca3000_read_first_n_hw_rb,
- .data_available = sca3000_ring_buf_data_available,
- .release = sca3000_ring_release,
-
- .modes = INDIO_BUFFER_HARDWARE,
-};
-
-int sca3000_configure_ring(struct iio_dev *indio_dev)
-{
- struct iio_buffer *buffer;
-
- buffer = sca3000_rb_allocate(indio_dev);
- if (!buffer)
- return -ENOMEM;
- indio_dev->modes |= INDIO_BUFFER_HARDWARE;
-
- indio_dev->buffer->access = &sca3000_ring_access_funcs;
-
- iio_device_attach_buffer(indio_dev, buffer);
-
- return 0;
-}
-
-void sca3000_unconfigure_ring(struct iio_dev *indio_dev)
-{
- iio_buffer_put(indio_dev->buffer);
-}
-
-static inline
-int __sca3000_hw_ring_state_set(struct iio_dev *indio_dev, bool state)
-{
- struct sca3000_state *st = iio_priv(indio_dev);
- int ret;
-
- mutex_lock(&st->lock);
- ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
- if (ret)
- goto error_ret;
- if (state) {
- dev_info(&indio_dev->dev, "supposedly enabling ring buffer\n");
- ret = sca3000_write_reg(st,
- SCA3000_REG_ADDR_MODE,
- (st->rx[0] | SCA3000_RING_BUF_ENABLE));
- } else
- ret = sca3000_write_reg(st,
- SCA3000_REG_ADDR_MODE,
- (st->rx[0] & ~SCA3000_RING_BUF_ENABLE));
-error_ret:
- mutex_unlock(&st->lock);
-
- return ret;
-}
-
-/**
- * sca3000_hw_ring_preenable() hw ring buffer preenable function
- *
- * Very simple enable function as the chip will allows normal reads
- * during ring buffer operation so as long as it is indeed running
- * before we notify the core, the precise ordering does not matter.
- **/
-static int sca3000_hw_ring_preenable(struct iio_dev *indio_dev)
-{
- return __sca3000_hw_ring_state_set(indio_dev, 1);
-}
-
-static int sca3000_hw_ring_postdisable(struct iio_dev *indio_dev)
-{
- return __sca3000_hw_ring_state_set(indio_dev, 0);
-}
-
-static const struct iio_buffer_setup_ops sca3000_ring_setup_ops = {
- .preenable = &sca3000_hw_ring_preenable,
- .postdisable = &sca3000_hw_ring_postdisable,
-};
-
-void sca3000_register_ring_funcs(struct iio_dev *indio_dev)
-{
- indio_dev->setup_ops = &sca3000_ring_setup_ops;
-}
-
-/**
- * sca3000_ring_int_process() ring specific interrupt handling.
- *
- * This is only split from the main interrupt handler so as to
- * reduce the amount of code if the ring buffer is not enabled.
- **/
-void sca3000_ring_int_process(u8 val, struct iio_buffer *ring)
-{
- if (val & (SCA3000_INT_STATUS_THREE_QUARTERS |
- SCA3000_INT_STATUS_HALF)) {
- ring->stufftoread = true;
- wake_up_interruptible(&ring->pollq);
- }
-}
diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile
index 3cdd83ccec8e..ac09485923b6 100644
--- a/drivers/staging/iio/adc/Makefile
+++ b/drivers/staging/iio/adc/Makefile
@@ -2,7 +2,6 @@
# Makefile for industrial I/O ADC drivers
#
-ad7606-y := ad7606_core.o ad7606_ring.o
obj-$(CONFIG_AD7606_IFACE_PARALLEL) += ad7606_par.o
obj-$(CONFIG_AD7606_IFACE_SPI) += ad7606_spi.o
obj-$(CONFIG_AD7606) += ad7606.o
diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c
index 1cf6b79801a9..1fb68c01abd5 100644
--- a/drivers/staging/iio/adc/ad7192.c
+++ b/drivers/staging/iio/adc/ad7192.c
@@ -152,7 +152,8 @@
*/
struct ad7192_state {
- struct regulator *reg;
+ struct regulator *avdd;
+ struct regulator *dvdd;
u16 int_vref_mv;
u32 mclk;
u32 f_order;
@@ -322,57 +323,6 @@ out:
return ret;
}
-static ssize_t ad7192_read_frequency(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct ad7192_state *st = iio_priv(indio_dev);
-
- return sprintf(buf, "%d\n", st->mclk /
- (st->f_order * 1024 * AD7192_MODE_RATE(st->mode)));
-}
-
-static ssize_t ad7192_write_frequency(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct ad7192_state *st = iio_priv(indio_dev);
- unsigned long lval;
- int div, ret;
-
- ret = kstrtoul(buf, 10, &lval);
- if (ret)
- return ret;
- if (lval == 0)
- return -EINVAL;
-
- ret = iio_device_claim_direct_mode(indio_dev);
- if (ret)
- return ret;
-
- div = st->mclk / (lval * st->f_order * 1024);
- if (div < 1 || div > 1023) {
- ret = -EINVAL;
- goto out;
- }
-
- st->mode &= ~AD7192_MODE_RATE(-1);
- st->mode |= AD7192_MODE_RATE(div);
- ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode);
-
-out:
- iio_device_release_direct_mode(indio_dev);
-
- return ret ? ret : len;
-}
-
-static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
- ad7192_read_frequency,
- ad7192_write_frequency);
-
static ssize_t
ad7192_show_scale_available(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -471,7 +421,6 @@ static IIO_DEVICE_ATTR(ac_excitation_en, S_IRUGO | S_IWUSR,
AD7192_REG_MODE);
static struct attribute *ad7192_attributes[] = {
- &iio_dev_attr_sampling_frequency.dev_attr.attr,
&iio_dev_attr_in_v_m_v_scale_available.dev_attr.attr,
&iio_dev_attr_in_voltage_scale_available.dev_attr.attr,
&iio_dev_attr_bridge_switch_en.dev_attr.attr,
@@ -484,7 +433,6 @@ static const struct attribute_group ad7192_attribute_group = {
};
static struct attribute *ad7195_attributes[] = {
- &iio_dev_attr_sampling_frequency.dev_attr.attr,
&iio_dev_attr_in_v_m_v_scale_available.dev_attr.attr,
&iio_dev_attr_in_voltage_scale_available.dev_attr.attr,
&iio_dev_attr_bridge_switch_en.dev_attr.attr,
@@ -536,6 +484,10 @@ static int ad7192_read_raw(struct iio_dev *indio_dev,
if (chan->type == IIO_TEMP)
*val -= 273 * ad7192_get_temp_scale(unipolar);
return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ *val = st->mclk /
+ (st->f_order * 1024 * AD7192_MODE_RATE(st->mode));
+ return IIO_VAL_INT;
}
return -EINVAL;
@@ -548,7 +500,7 @@ static int ad7192_write_raw(struct iio_dev *indio_dev,
long mask)
{
struct ad7192_state *st = iio_priv(indio_dev);
- int ret, i;
+ int ret, i, div;
unsigned int tmp;
ret = iio_device_claim_direct_mode(indio_dev);
@@ -572,6 +524,22 @@ static int ad7192_write_raw(struct iio_dev *indio_dev,
break;
}
break;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ if (!val) {
+ ret = -EINVAL;
+ break;
+ }
+
+ div = st->mclk / (val * st->f_order * 1024);
+ if (div < 1 || div > 1023) {
+ ret = -EINVAL;
+ break;
+ }
+
+ st->mode &= ~AD7192_MODE_RATE(-1);
+ st->mode |= AD7192_MODE_RATE(div);
+ ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode);
+ break;
default:
ret = -EINVAL;
}
@@ -585,7 +553,14 @@ static int ad7192_write_raw_get_fmt(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
long mask)
{
- return IIO_VAL_INT_PLUS_NANO;
+ switch (mask) {
+ case IIO_CHAN_INFO_SCALE:
+ return IIO_VAL_INT_PLUS_NANO;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ return IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
}
static const struct iio_info ad7192_info = {
@@ -659,15 +634,30 @@ static int ad7192_probe(struct spi_device *spi)
st = iio_priv(indio_dev);
- st->reg = devm_regulator_get(&spi->dev, "vcc");
- if (!IS_ERR(st->reg)) {
- ret = regulator_enable(st->reg);
- if (ret)
- return ret;
+ st->avdd = devm_regulator_get(&spi->dev, "avdd");
+ if (IS_ERR(st->avdd))
+ return PTR_ERR(st->avdd);
- voltage_uv = regulator_get_voltage(st->reg);
+ ret = regulator_enable(st->avdd);
+ if (ret) {
+ dev_err(&spi->dev, "Failed to enable specified AVdd supply\n");
+ return ret;
+ }
+
+ st->dvdd = devm_regulator_get(&spi->dev, "dvdd");
+ if (IS_ERR(st->dvdd)) {
+ ret = PTR_ERR(st->dvdd);
+ goto error_disable_avdd;
}
+ ret = regulator_enable(st->dvdd);
+ if (ret) {
+ dev_err(&spi->dev, "Failed to enable specified DVdd supply\n");
+ goto error_disable_avdd;
+ }
+
+ voltage_uv = regulator_get_voltage(st->avdd);
+
if (pdata->vref_mv)
st->int_vref_mv = pdata->vref_mv;
else if (voltage_uv)
@@ -701,7 +691,7 @@ static int ad7192_probe(struct spi_device *spi)
ret = ad_sd_setup_buffer_and_trigger(indio_dev);
if (ret)
- goto error_disable_reg;
+ goto error_disable_dvdd;
ret = ad7192_setup(st, pdata);
if (ret)
@@ -714,9 +704,10 @@ static int ad7192_probe(struct spi_device *spi)
error_remove_trigger:
ad_sd_cleanup_buffer_and_trigger(indio_dev);
-error_disable_reg:
- if (!IS_ERR(st->reg))
- regulator_disable(st->reg);
+error_disable_dvdd:
+ regulator_disable(st->dvdd);
+error_disable_avdd:
+ regulator_disable(st->avdd);
return ret;
}
@@ -729,8 +720,8 @@ static int ad7192_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
ad_sd_cleanup_buffer_and_trigger(indio_dev);
- if (!IS_ERR(st->reg))
- regulator_disable(st->reg);
+ regulator_disable(st->dvdd);
+ regulator_disable(st->avdd);
return 0;
}
diff --git a/drivers/staging/iio/adc/ad7280a.c b/drivers/staging/iio/adc/ad7280a.c
index b460dda7eb65..ee679ac0368f 100644
--- a/drivers/staging/iio/adc/ad7280a.c
+++ b/drivers/staging/iio/adc/ad7280a.c
@@ -777,7 +777,7 @@ static struct attribute *ad7280_event_attributes[] = {
NULL,
};
-static struct attribute_group ad7280_event_attrs_group = {
+static const struct attribute_group ad7280_event_attrs_group = {
.attrs = ad7280_event_attributes,
};
diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606.c
index f79ee61851f6..453190864b2f 100644
--- a/drivers/staging/iio/adc/ad7606_core.c
+++ b/drivers/staging/iio/adc/ad7606.c
@@ -13,7 +13,7 @@
#include <linux/sysfs.h>
#include <linux/regulator/consumer.h>
#include <linux/err.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/module.h>
@@ -21,58 +21,109 @@
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
#include "ad7606.h"
-int ad7606_reset(struct ad7606_state *st)
+static int ad7606_reset(struct ad7606_state *st)
{
- if (gpio_is_valid(st->pdata->gpio_reset)) {
- gpio_set_value(st->pdata->gpio_reset, 1);
+ if (st->gpio_reset) {
+ gpiod_set_value(st->gpio_reset, 1);
ndelay(100); /* t_reset >= 100ns */
- gpio_set_value(st->pdata->gpio_reset, 0);
+ gpiod_set_value(st->gpio_reset, 0);
return 0;
}
return -ENODEV;
}
+static int ad7606_read_samples(struct ad7606_state *st)
+{
+ unsigned int num = st->chip_info->num_channels;
+ u16 *data = st->data;
+ int ret;
+
+ /*
+ * The frstdata signal is set to high while and after reading the sample
+ * of the first channel and low for all other channels. This can be used
+ * to check that the incoming data is correctly aligned. During normal
+ * operation the data should never become unaligned, but some glitch or
+ * electrostatic discharge might cause an extra read or clock cycle.
+ * Monitoring the frstdata signal allows to recover from such failure
+ * situations.
+ */
+
+ if (st->gpio_frstdata) {
+ ret = st->bops->read_block(st->dev, 1, data);
+ if (ret)
+ return ret;
+
+ if (!gpiod_get_value(st->gpio_frstdata)) {
+ ad7606_reset(st);
+ return -EIO;
+ }
+
+ data++;
+ num--;
+ }
+
+ return st->bops->read_block(st->dev, num, data);
+}
+
+static irqreturn_t ad7606_trigger_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct ad7606_state *st = iio_priv(pf->indio_dev);
+
+ gpiod_set_value(st->gpio_convst, 1);
+
+ return IRQ_HANDLED;
+}
+
+/**
+ * ad7606_poll_bh_to_ring() bh of trigger launched polling to ring buffer
+ * @work_s: the work struct through which this was scheduled
+ *
+ * Currently there is no option in this driver to disable the saving of
+ * timestamps within the ring.
+ * I think the one copy of this at a time was to avoid problems if the
+ * trigger was set far too high and the reads then locked up the computer.
+ **/
+static void ad7606_poll_bh_to_ring(struct work_struct *work_s)
+{
+ struct ad7606_state *st = container_of(work_s, struct ad7606_state,
+ poll_work);
+ struct iio_dev *indio_dev = iio_priv_to_dev(st);
+ int ret;
+
+ ret = ad7606_read_samples(st);
+ if (ret == 0)
+ iio_push_to_buffers_with_timestamp(indio_dev, st->data,
+ iio_get_time_ns(indio_dev));
+
+ gpiod_set_value(st->gpio_convst, 0);
+ iio_trigger_notify_done(indio_dev->trig);
+}
+
static int ad7606_scan_direct(struct iio_dev *indio_dev, unsigned int ch)
{
struct ad7606_state *st = iio_priv(indio_dev);
int ret;
st->done = false;
- gpio_set_value(st->pdata->gpio_convst, 1);
+ gpiod_set_value(st->gpio_convst, 1);
ret = wait_event_interruptible(st->wq_data_avail, st->done);
if (ret)
goto error_ret;
- if (gpio_is_valid(st->pdata->gpio_frstdata)) {
- ret = st->bops->read_block(st->dev, 1, st->data);
- if (ret)
- goto error_ret;
- if (!gpio_get_value(st->pdata->gpio_frstdata)) {
- /* This should never happen */
- ad7606_reset(st);
- ret = -EIO;
- goto error_ret;
- }
- ret = st->bops->read_block(st->dev,
- st->chip_info->num_channels - 1, &st->data[1]);
- if (ret)
- goto error_ret;
- } else {
- ret = st->bops->read_block(st->dev,
- st->chip_info->num_channels, st->data);
- if (ret)
- goto error_ret;
- }
-
- ret = st->data[ch];
+ ret = ad7606_read_samples(st);
+ if (ret == 0)
+ ret = st->data[ch];
error_ret:
- gpio_set_value(st->pdata->gpio_convst, 0);
+ gpiod_set_value(st->gpio_convst, 0);
return ret;
}
@@ -103,6 +154,9 @@ static int ad7606_read_raw(struct iio_dev *indio_dev,
*val = st->range * 2;
*val2 = st->chip_info->channels[0].scan_type.realbits;
return IIO_VAL_FRACTIONAL_LOG2;
+ case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
+ *val = st->oversampling;
+ return IIO_VAL_INT;
}
return -EINVAL;
}
@@ -129,12 +183,11 @@ static ssize_t ad7606_store_range(struct device *dev,
if (ret)
return ret;
- if (!(lval == 5000 || lval == 10000)) {
- dev_err(dev, "range is not supported\n");
+ if (!(lval == 5000 || lval == 10000))
return -EINVAL;
- }
+
mutex_lock(&indio_dev->mlock);
- gpio_set_value(st->pdata->gpio_range, lval == 10000);
+ gpiod_set_value(st->gpio_range, lval == 10000);
st->range = lval;
mutex_unlock(&indio_dev->mlock);
@@ -145,19 +198,9 @@ static IIO_DEVICE_ATTR(in_voltage_range, S_IRUGO | S_IWUSR,
ad7606_show_range, ad7606_store_range, 0);
static IIO_CONST_ATTR(in_voltage_range_available, "5000 10000");
-static ssize_t ad7606_show_oversampling_ratio(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct ad7606_state *st = iio_priv(indio_dev);
-
- return sprintf(buf, "%u\n", st->oversampling);
-}
-
static int ad7606_oversampling_get_index(unsigned int val)
{
- unsigned char supported[] = {0, 2, 4, 8, 16, 32, 64};
+ unsigned char supported[] = {1, 2, 4, 8, 16, 32, 64};
int i;
for (i = 0; i < ARRAY_SIZE(supported); i++)
@@ -167,44 +210,45 @@ static int ad7606_oversampling_get_index(unsigned int val)
return -EINVAL;
}
-static ssize_t ad7606_store_oversampling_ratio(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
+static int ad7606_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val,
+ int val2,
+ long mask)
{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ad7606_state *st = iio_priv(indio_dev);
- unsigned long lval;
+ int values[3];
int ret;
- ret = kstrtoul(buf, 10, &lval);
- if (ret)
- return ret;
+ switch (mask) {
+ case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
+ if (val2)
+ return -EINVAL;
+ ret = ad7606_oversampling_get_index(val);
+ if (ret < 0)
+ return ret;
- ret = ad7606_oversampling_get_index(lval);
- if (ret < 0) {
- dev_err(dev, "oversampling %lu is not supported\n", lval);
- return ret;
- }
+ values[0] = (ret >> 0) & 1;
+ values[1] = (ret >> 1) & 1;
+ values[2] = (ret >> 2) & 1;
- mutex_lock(&indio_dev->mlock);
- gpio_set_value(st->pdata->gpio_os0, (ret >> 0) & 1);
- gpio_set_value(st->pdata->gpio_os1, (ret >> 1) & 1);
- gpio_set_value(st->pdata->gpio_os1, (ret >> 2) & 1);
- st->oversampling = lval;
- mutex_unlock(&indio_dev->mlock);
+ mutex_lock(&indio_dev->mlock);
+ gpiod_set_array_value(ARRAY_SIZE(values), st->gpio_os->desc,
+ values);
+ st->oversampling = val;
+ mutex_unlock(&indio_dev->mlock);
- return count;
+ return 0;
+ default:
+ return -EINVAL;
+ }
}
-static IIO_DEVICE_ATTR(oversampling_ratio, S_IRUGO | S_IWUSR,
- ad7606_show_oversampling_ratio,
- ad7606_store_oversampling_ratio, 0);
-static IIO_CONST_ATTR(oversampling_ratio_available, "0 2 4 8 16 32 64");
+static IIO_CONST_ATTR(oversampling_ratio_available, "1 2 4 8 16 32 64");
static struct attribute *ad7606_attributes_os_and_range[] = {
&iio_dev_attr_in_voltage_range.dev_attr.attr,
&iio_const_attr_in_voltage_range_available.dev_attr.attr,
- &iio_dev_attr_oversampling_ratio.dev_attr.attr,
&iio_const_attr_oversampling_ratio_available.dev_attr.attr,
NULL,
};
@@ -214,7 +258,6 @@ static const struct attribute_group ad7606_attribute_group_os_and_range = {
};
static struct attribute *ad7606_attributes_os[] = {
- &iio_dev_attr_oversampling_ratio.dev_attr.attr,
&iio_const_attr_oversampling_ratio_available.dev_attr.attr,
NULL,
};
@@ -241,6 +284,8 @@ static const struct attribute_group ad7606_attribute_group_range = {
.address = num, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),\
+ .info_mask_shared_by_all = \
+ BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
.scan_index = num, \
.scan_type = { \
.sign = 's', \
@@ -267,20 +312,14 @@ static const struct ad7606_chip_info ad7606_chip_info_tbl[] = {
* More devices added in future
*/
[ID_AD7606_8] = {
- .name = "ad7606",
- .int_vref_mv = 2500,
.channels = ad7606_channels,
.num_channels = 9,
},
[ID_AD7606_6] = {
- .name = "ad7606-6",
- .int_vref_mv = 2500,
.channels = ad7606_channels,
.num_channels = 7,
},
[ID_AD7606_4] = {
- .name = "ad7606-4",
- .int_vref_mv = 2500,
.channels = ad7606_channels,
.num_channels = 5,
},
@@ -288,119 +327,34 @@ static const struct ad7606_chip_info ad7606_chip_info_tbl[] = {
static int ad7606_request_gpios(struct ad7606_state *st)
{
- struct gpio gpio_array[3] = {
- [0] = {
- .gpio = st->pdata->gpio_os0,
- .flags = GPIOF_DIR_OUT | ((st->oversampling & 1) ?
- GPIOF_INIT_HIGH : GPIOF_INIT_LOW),
- .label = "AD7606_OS0",
- },
- [1] = {
- .gpio = st->pdata->gpio_os1,
- .flags = GPIOF_DIR_OUT | ((st->oversampling & 2) ?
- GPIOF_INIT_HIGH : GPIOF_INIT_LOW),
- .label = "AD7606_OS1",
- },
- [2] = {
- .gpio = st->pdata->gpio_os2,
- .flags = GPIOF_DIR_OUT | ((st->oversampling & 4) ?
- GPIOF_INIT_HIGH : GPIOF_INIT_LOW),
- .label = "AD7606_OS2",
- },
- };
- int ret;
-
- if (gpio_is_valid(st->pdata->gpio_convst)) {
- ret = gpio_request_one(st->pdata->gpio_convst,
- GPIOF_OUT_INIT_LOW,
- "AD7606_CONVST");
- if (ret) {
- dev_err(st->dev, "failed to request GPIO CONVST\n");
- goto error_ret;
- }
- } else {
- ret = -EIO;
- goto error_ret;
- }
-
- if (gpio_is_valid(st->pdata->gpio_os0) &&
- gpio_is_valid(st->pdata->gpio_os1) &&
- gpio_is_valid(st->pdata->gpio_os2)) {
- ret = gpio_request_array(gpio_array, ARRAY_SIZE(gpio_array));
- if (ret < 0)
- goto error_free_convst;
- }
-
- if (gpio_is_valid(st->pdata->gpio_reset)) {
- ret = gpio_request_one(st->pdata->gpio_reset,
- GPIOF_OUT_INIT_LOW,
- "AD7606_RESET");
- if (ret < 0)
- goto error_free_os;
- }
-
- if (gpio_is_valid(st->pdata->gpio_range)) {
- ret = gpio_request_one(st->pdata->gpio_range, GPIOF_DIR_OUT |
- ((st->range == 10000) ? GPIOF_INIT_HIGH :
- GPIOF_INIT_LOW), "AD7606_RANGE");
- if (ret < 0)
- goto error_free_reset;
- }
- if (gpio_is_valid(st->pdata->gpio_stby)) {
- ret = gpio_request_one(st->pdata->gpio_stby,
- GPIOF_OUT_INIT_HIGH,
- "AD7606_STBY");
- if (ret < 0)
- goto error_free_range;
- }
-
- if (gpio_is_valid(st->pdata->gpio_frstdata)) {
- ret = gpio_request_one(st->pdata->gpio_frstdata, GPIOF_IN,
- "AD7606_FRSTDATA");
- if (ret < 0)
- goto error_free_stby;
- }
-
- return 0;
-
-error_free_stby:
- if (gpio_is_valid(st->pdata->gpio_stby))
- gpio_free(st->pdata->gpio_stby);
-error_free_range:
- if (gpio_is_valid(st->pdata->gpio_range))
- gpio_free(st->pdata->gpio_range);
-error_free_reset:
- if (gpio_is_valid(st->pdata->gpio_reset))
- gpio_free(st->pdata->gpio_reset);
-error_free_os:
- if (gpio_is_valid(st->pdata->gpio_os0) &&
- gpio_is_valid(st->pdata->gpio_os1) &&
- gpio_is_valid(st->pdata->gpio_os2))
- gpio_free_array(gpio_array, ARRAY_SIZE(gpio_array));
-error_free_convst:
- gpio_free(st->pdata->gpio_convst);
-error_ret:
- return ret;
-}
-
-static void ad7606_free_gpios(struct ad7606_state *st)
-{
- if (gpio_is_valid(st->pdata->gpio_frstdata))
- gpio_free(st->pdata->gpio_frstdata);
- if (gpio_is_valid(st->pdata->gpio_stby))
- gpio_free(st->pdata->gpio_stby);
- if (gpio_is_valid(st->pdata->gpio_range))
- gpio_free(st->pdata->gpio_range);
- if (gpio_is_valid(st->pdata->gpio_reset))
- gpio_free(st->pdata->gpio_reset);
- if (gpio_is_valid(st->pdata->gpio_os0) &&
- gpio_is_valid(st->pdata->gpio_os1) &&
- gpio_is_valid(st->pdata->gpio_os2)) {
- gpio_free(st->pdata->gpio_os2);
- gpio_free(st->pdata->gpio_os1);
- gpio_free(st->pdata->gpio_os0);
- }
- gpio_free(st->pdata->gpio_convst);
+ struct device *dev = st->dev;
+
+ st->gpio_convst = devm_gpiod_get(dev, "conversion-start",
+ GPIOD_OUT_LOW);
+ if (IS_ERR(st->gpio_convst))
+ return PTR_ERR(st->gpio_convst);
+
+ st->gpio_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
+ if (IS_ERR(st->gpio_reset))
+ return PTR_ERR(st->gpio_reset);
+
+ st->gpio_range = devm_gpiod_get_optional(dev, "range", GPIOD_OUT_LOW);
+ if (IS_ERR(st->gpio_range))
+ return PTR_ERR(st->gpio_range);
+
+ st->gpio_standby = devm_gpiod_get_optional(dev, "standby",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(st->gpio_standby))
+ return PTR_ERR(st->gpio_standby);
+
+ st->gpio_frstdata = devm_gpiod_get_optional(dev, "first-data",
+ GPIOD_IN);
+ if (IS_ERR(st->gpio_frstdata))
+ return PTR_ERR(st->gpio_frstdata);
+
+ st->gpio_os = devm_gpiod_get_array_optional(dev, "oversampling-ratio",
+ GPIOD_OUT_LOW);
+ return PTR_ERR_OR_ZERO(st->gpio_os);
}
/**
@@ -429,12 +383,14 @@ static const struct iio_info ad7606_info_no_os_or_range = {
static const struct iio_info ad7606_info_os_and_range = {
.driver_module = THIS_MODULE,
.read_raw = &ad7606_read_raw,
+ .write_raw = &ad7606_write_raw,
.attrs = &ad7606_attribute_group_os_and_range,
};
static const struct iio_info ad7606_info_os = {
.driver_module = THIS_MODULE,
.read_raw = &ad7606_read_raw,
+ .write_raw = &ad7606_write_raw,
.attrs = &ad7606_attribute_group_os,
};
@@ -444,81 +400,73 @@ static const struct iio_info ad7606_info_range = {
.attrs = &ad7606_attribute_group_range,
};
-struct iio_dev *ad7606_probe(struct device *dev, int irq,
- void __iomem *base_address,
- unsigned int id,
- const struct ad7606_bus_ops *bops)
+int ad7606_probe(struct device *dev, int irq, void __iomem *base_address,
+ const char *name, unsigned int id,
+ const struct ad7606_bus_ops *bops)
{
- struct ad7606_platform_data *pdata = dev->platform_data;
struct ad7606_state *st;
int ret;
struct iio_dev *indio_dev;
indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
if (!indio_dev)
- return ERR_PTR(-ENOMEM);
+ return -ENOMEM;
st = iio_priv(indio_dev);
st->dev = dev;
st->bops = bops;
st->base_address = base_address;
- st->range = pdata->default_range == 10000 ? 10000 : 5000;
+ st->range = 5000;
+ st->oversampling = 1;
+ INIT_WORK(&st->poll_work, &ad7606_poll_bh_to_ring);
- ret = ad7606_oversampling_get_index(pdata->default_os);
- if (ret < 0) {
- dev_warn(dev, "oversampling %d is not supported\n",
- pdata->default_os);
- st->oversampling = 0;
- } else {
- st->oversampling = pdata->default_os;
- }
+ st->reg = devm_regulator_get(dev, "avcc");
+ if (IS_ERR(st->reg))
+ return PTR_ERR(st->reg);
- st->reg = devm_regulator_get(dev, "vcc");
- if (!IS_ERR(st->reg)) {
- ret = regulator_enable(st->reg);
- if (ret)
- return ERR_PTR(ret);
+ ret = regulator_enable(st->reg);
+ if (ret) {
+ dev_err(dev, "Failed to enable specified AVcc supply\n");
+ return ret;
}
- st->pdata = pdata;
+ ret = ad7606_request_gpios(st);
+ if (ret)
+ goto error_disable_reg;
+
st->chip_info = &ad7606_chip_info_tbl[id];
indio_dev->dev.parent = dev;
- if (gpio_is_valid(st->pdata->gpio_os0) &&
- gpio_is_valid(st->pdata->gpio_os1) &&
- gpio_is_valid(st->pdata->gpio_os2)) {
- if (gpio_is_valid(st->pdata->gpio_range))
+ if (st->gpio_os) {
+ if (st->gpio_range)
indio_dev->info = &ad7606_info_os_and_range;
else
indio_dev->info = &ad7606_info_os;
} else {
- if (gpio_is_valid(st->pdata->gpio_range))
+ if (st->gpio_range)
indio_dev->info = &ad7606_info_range;
else
indio_dev->info = &ad7606_info_no_os_or_range;
}
indio_dev->modes = INDIO_DIRECT_MODE;
- indio_dev->name = st->chip_info->name;
+ indio_dev->name = name;
indio_dev->channels = st->chip_info->channels;
indio_dev->num_channels = st->chip_info->num_channels;
init_waitqueue_head(&st->wq_data_avail);
- ret = ad7606_request_gpios(st);
- if (ret)
- goto error_disable_reg;
-
ret = ad7606_reset(st);
if (ret)
dev_warn(st->dev, "failed to RESET: no RESET GPIO specified\n");
- ret = request_irq(irq, ad7606_interrupt,
- IRQF_TRIGGER_FALLING, st->chip_info->name, indio_dev);
+ ret = request_irq(irq, ad7606_interrupt, IRQF_TRIGGER_FALLING, name,
+ indio_dev);
if (ret)
- goto error_free_gpios;
+ goto error_disable_reg;
- ret = ad7606_register_ring_funcs_and_init(indio_dev);
+ ret = iio_triggered_buffer_setup(indio_dev, &ad7606_trigger_handler,
+ NULL, NULL);
if (ret)
goto error_free_irq;
@@ -526,35 +474,31 @@ struct iio_dev *ad7606_probe(struct device *dev, int irq,
if (ret)
goto error_unregister_ring;
- return indio_dev;
+ dev_set_drvdata(dev, indio_dev);
+
+ return 0;
error_unregister_ring:
- ad7606_ring_cleanup(indio_dev);
+ iio_triggered_buffer_cleanup(indio_dev);
error_free_irq:
free_irq(irq, indio_dev);
-error_free_gpios:
- ad7606_free_gpios(st);
-
error_disable_reg:
- if (!IS_ERR(st->reg))
- regulator_disable(st->reg);
- return ERR_PTR(ret);
+ regulator_disable(st->reg);
+ return ret;
}
EXPORT_SYMBOL_GPL(ad7606_probe);
-int ad7606_remove(struct iio_dev *indio_dev, int irq)
+int ad7606_remove(struct device *dev, int irq)
{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct ad7606_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
- ad7606_ring_cleanup(indio_dev);
+ iio_triggered_buffer_cleanup(indio_dev);
free_irq(irq, indio_dev);
- if (!IS_ERR(st->reg))
- regulator_disable(st->reg);
-
- ad7606_free_gpios(st);
+ regulator_disable(st->reg);
return 0;
}
@@ -567,10 +511,9 @@ static int ad7606_suspend(struct device *dev)
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct ad7606_state *st = iio_priv(indio_dev);
- if (gpio_is_valid(st->pdata->gpio_stby)) {
- if (gpio_is_valid(st->pdata->gpio_range))
- gpio_set_value(st->pdata->gpio_range, 1);
- gpio_set_value(st->pdata->gpio_stby, 0);
+ if (st->gpio_standby) {
+ gpiod_set_value(st->gpio_range, 1);
+ gpiod_set_value(st->gpio_standby, 0);
}
return 0;
@@ -581,12 +524,9 @@ static int ad7606_resume(struct device *dev)
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct ad7606_state *st = iio_priv(indio_dev);
- if (gpio_is_valid(st->pdata->gpio_stby)) {
- if (gpio_is_valid(st->pdata->gpio_range))
- gpio_set_value(st->pdata->gpio_range,
- st->range == 10000);
-
- gpio_set_value(st->pdata->gpio_stby, 1);
+ if (st->gpio_standby) {
+ gpiod_set_value(st->gpio_range, st->range == 10000);
+ gpiod_set_value(st->gpio_standby, 1);
ad7606_reset(st);
}
diff --git a/drivers/staging/iio/adc/ad7606.h b/drivers/staging/iio/adc/ad7606.h
index 39f50440d915..746f9553d2ba 100644
--- a/drivers/staging/iio/adc/ad7606.h
+++ b/drivers/staging/iio/adc/ad7606.h
@@ -9,48 +9,14 @@
#ifndef IIO_ADC_AD7606_H_
#define IIO_ADC_AD7606_H_
-/*
- * TODO: struct ad7606_platform_data needs to go into include/linux/iio
- */
-
-/**
- * struct ad7606_platform_data - platform/board specific information
- * @default_os: default oversampling value {0, 2, 4, 8, 16, 32, 64}
- * @default_range: default range +/-{5000, 10000} mVolt
- * @gpio_convst: number of gpio connected to the CONVST pin
- * @gpio_reset: gpio connected to the RESET pin, if not used set to -1
- * @gpio_range: gpio connected to the RANGE pin, if not used set to -1
- * @gpio_os0: gpio connected to the OS0 pin, if not used set to -1
- * @gpio_os1: gpio connected to the OS1 pin, if not used set to -1
- * @gpio_os2: gpio connected to the OS2 pin, if not used set to -1
- * @gpio_frstdata: gpio connected to the FRSTDAT pin, if not used set to -1
- * @gpio_stby: gpio connected to the STBY pin, if not used set to -1
- */
-
-struct ad7606_platform_data {
- unsigned int default_os;
- unsigned int default_range;
- unsigned int gpio_convst;
- unsigned int gpio_reset;
- unsigned int gpio_range;
- unsigned int gpio_os0;
- unsigned int gpio_os1;
- unsigned int gpio_os2;
- unsigned int gpio_frstdata;
- unsigned int gpio_stby;
-};
-
/**
* struct ad7606_chip_info - chip specific information
* @name: identification string for chip
- * @int_vref_mv: the internal reference voltage
* @channels: channel specification
* @num_channels: number of channels
*/
struct ad7606_chip_info {
- const char *name;
- u16 int_vref_mv;
const struct iio_chan_spec *channels;
unsigned int num_channels;
};
@@ -62,7 +28,6 @@ struct ad7606_chip_info {
struct ad7606_state {
struct device *dev;
const struct ad7606_chip_info *chip_info;
- struct ad7606_platform_data *pdata;
struct regulator *reg;
struct work_struct poll_work;
wait_queue_head_t wq_data_avail;
@@ -72,12 +37,19 @@ struct ad7606_state {
bool done;
void __iomem *base_address;
+ struct gpio_desc *gpio_convst;
+ struct gpio_desc *gpio_reset;
+ struct gpio_desc *gpio_range;
+ struct gpio_desc *gpio_standby;
+ struct gpio_desc *gpio_frstdata;
+ struct gpio_descs *gpio_os;
+
/*
* DMA (thus cache coherency maintenance) requires the
* transfer buffers to live in their own cache lines.
+ * 8 * 16-bit samples + 64-bit timestamp
*/
-
- unsigned short data[8] ____cacheline_aligned;
+ unsigned short data[12] ____cacheline_aligned;
};
struct ad7606_bus_ops {
@@ -85,11 +57,10 @@ struct ad7606_bus_ops {
int (*read_block)(struct device *, int, void *);
};
-struct iio_dev *ad7606_probe(struct device *dev, int irq,
- void __iomem *base_address, unsigned int id,
- const struct ad7606_bus_ops *bops);
-int ad7606_remove(struct iio_dev *indio_dev, int irq);
-int ad7606_reset(struct ad7606_state *st);
+int ad7606_probe(struct device *dev, int irq, void __iomem *base_address,
+ const char *name, unsigned int id,
+ const struct ad7606_bus_ops *bops);
+int ad7606_remove(struct device *dev, int irq);
enum ad7606_supported_device_ids {
ID_AD7606_8,
@@ -97,9 +68,6 @@ enum ad7606_supported_device_ids {
ID_AD7606_4
};
-int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev);
-void ad7606_ring_cleanup(struct iio_dev *indio_dev);
-
#ifdef CONFIG_PM_SLEEP
extern const struct dev_pm_ops ad7606_pm_ops;
#define AD7606_PM_OPS (&ad7606_pm_ops)
diff --git a/drivers/staging/iio/adc/ad7606_par.c b/drivers/staging/iio/adc/ad7606_par.c
index 84d23930fdde..cd6c410c0484 100644
--- a/drivers/staging/iio/adc/ad7606_par.c
+++ b/drivers/staging/iio/adc/ad7606_par.c
@@ -49,8 +49,8 @@ static const struct ad7606_bus_ops ad7606_par8_bops = {
static int ad7606_par_probe(struct platform_device *pdev)
{
+ const struct platform_device_id *id = platform_get_device_id(pdev);
struct resource *res;
- struct iio_dev *indio_dev;
void __iomem *addr;
resource_size_t remap_size;
int irq;
@@ -68,26 +68,15 @@ static int ad7606_par_probe(struct platform_device *pdev)
remap_size = resource_size(res);
- indio_dev = ad7606_probe(&pdev->dev, irq, addr,
- platform_get_device_id(pdev)->driver_data,
- remap_size > 1 ? &ad7606_par16_bops :
- &ad7606_par8_bops);
-
- if (IS_ERR(indio_dev))
- return PTR_ERR(indio_dev);
-
- platform_set_drvdata(pdev, indio_dev);
-
- return 0;
+ return ad7606_probe(&pdev->dev, irq, addr,
+ id->name, id->driver_data,
+ remap_size > 1 ? &ad7606_par16_bops :
+ &ad7606_par8_bops);
}
static int ad7606_par_remove(struct platform_device *pdev)
{
- struct iio_dev *indio_dev = platform_get_drvdata(pdev);
-
- ad7606_remove(indio_dev, platform_get_irq(pdev, 0));
-
- return 0;
+ return ad7606_remove(&pdev->dev, platform_get_irq(pdev, 0));
}
static const struct platform_device_id ad7606_driver_ids[] = {
diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c
deleted file mode 100644
index 0572df9aad85..000000000000
--- a/drivers/staging/iio/adc/ad7606_ring.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright 2011-2012 Analog Devices Inc.
- *
- * Licensed under the GPL-2.
- *
- */
-
-#include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/buffer.h>
-#include <linux/iio/trigger_consumer.h>
-#include <linux/iio/triggered_buffer.h>
-
-#include "ad7606.h"
-
-/**
- * ad7606_trigger_handler_th() th/bh of trigger launched polling to ring buffer
- *
- **/
-static irqreturn_t ad7606_trigger_handler_th_bh(int irq, void *p)
-{
- struct iio_poll_func *pf = p;
- struct ad7606_state *st = iio_priv(pf->indio_dev);
-
- gpio_set_value(st->pdata->gpio_convst, 1);
-
- return IRQ_HANDLED;
-}
-
-/**
- * ad7606_poll_bh_to_ring() bh of trigger launched polling to ring buffer
- * @work_s: the work struct through which this was scheduled
- *
- * Currently there is no option in this driver to disable the saving of
- * timestamps within the ring.
- * I think the one copy of this at a time was to avoid problems if the
- * trigger was set far too high and the reads then locked up the computer.
- **/
-static void ad7606_poll_bh_to_ring(struct work_struct *work_s)
-{
- struct ad7606_state *st = container_of(work_s, struct ad7606_state,
- poll_work);
- struct iio_dev *indio_dev = iio_priv_to_dev(st);
- __u8 *buf;
- int ret;
-
- buf = kzalloc(indio_dev->scan_bytes, GFP_KERNEL);
- if (!buf)
- return;
-
- if (gpio_is_valid(st->pdata->gpio_frstdata)) {
- ret = st->bops->read_block(st->dev, 1, buf);
- if (ret)
- goto done;
- if (!gpio_get_value(st->pdata->gpio_frstdata)) {
- /* This should never happen. However
- * some signal glitch caused by bad PCB desgin or
- * electrostatic discharge, could cause an extra read
- * or clock. This allows recovery.
- */
- ad7606_reset(st);
- goto done;
- }
- ret = st->bops->read_block(st->dev,
- st->chip_info->num_channels - 1, buf + 2);
- if (ret)
- goto done;
- } else {
- ret = st->bops->read_block(st->dev,
- st->chip_info->num_channels, buf);
- if (ret)
- goto done;
- }
-
- iio_push_to_buffers_with_timestamp(indio_dev, buf,
- iio_get_time_ns(indio_dev));
-done:
- gpio_set_value(st->pdata->gpio_convst, 0);
- iio_trigger_notify_done(indio_dev->trig);
- kfree(buf);
-}
-
-int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev)
-{
- struct ad7606_state *st = iio_priv(indio_dev);
-
- INIT_WORK(&st->poll_work, &ad7606_poll_bh_to_ring);
-
- return iio_triggered_buffer_setup(indio_dev,
- &ad7606_trigger_handler_th_bh, &ad7606_trigger_handler_th_bh,
- NULL);
-}
-
-void ad7606_ring_cleanup(struct iio_dev *indio_dev)
-{
- iio_triggered_buffer_cleanup(indio_dev);
-}
diff --git a/drivers/staging/iio/adc/ad7606_spi.c b/drivers/staging/iio/adc/ad7606_spi.c
index 9587fa86dc69..c9b1f26685f4 100644
--- a/drivers/staging/iio/adc/ad7606_spi.c
+++ b/drivers/staging/iio/adc/ad7606_spi.c
@@ -42,25 +42,16 @@ static const struct ad7606_bus_ops ad7606_spi_bops = {
static int ad7606_spi_probe(struct spi_device *spi)
{
- struct iio_dev *indio_dev;
+ const struct spi_device_id *id = spi_get_device_id(spi);
- indio_dev = ad7606_probe(&spi->dev, spi->irq, NULL,
- spi_get_device_id(spi)->driver_data,
- &ad7606_spi_bops);
-
- if (IS_ERR(indio_dev))
- return PTR_ERR(indio_dev);
-
- spi_set_drvdata(spi, indio_dev);
-
- return 0;
+ return ad7606_probe(&spi->dev, spi->irq, NULL,
+ id->name, id->driver_data,
+ &ad7606_spi_bops);
}
static int ad7606_spi_remove(struct spi_device *spi)
{
- struct iio_dev *indio_dev = dev_get_drvdata(&spi->dev);
-
- return ad7606_remove(indio_dev, spi->irq);
+ return ad7606_remove(&spi->dev, spi->irq);
}
static const struct spi_device_id ad7606_id[] = {
diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c
index c9a0c2aa602f..e14960038d3e 100644
--- a/drivers/staging/iio/adc/ad7780.c
+++ b/drivers/staging/iio/adc/ad7780.c
@@ -173,14 +173,16 @@ static int ad7780_probe(struct spi_device *spi)
ad_sd_init(&st->sd, indio_dev, spi, &ad7780_sigma_delta_info);
- st->reg = devm_regulator_get(&spi->dev, "vcc");
- if (!IS_ERR(st->reg)) {
- ret = regulator_enable(st->reg);
- if (ret)
- return ret;
-
- voltage_uv = regulator_get_voltage(st->reg);
+ st->reg = devm_regulator_get(&spi->dev, "avdd");
+ if (IS_ERR(st->reg))
+ return PTR_ERR(st->reg);
+
+ ret = regulator_enable(st->reg);
+ if (ret) {
+ dev_err(&spi->dev, "Failed to enable specified AVdd supply\n");
+ return ret;
}
+ voltage_uv = regulator_get_voltage(st->reg);
st->chip_info =
&ad7780_chip_info_tbl[spi_get_device_id(spi)->driver_data];
@@ -222,8 +224,7 @@ static int ad7780_probe(struct spi_device *spi)
error_cleanup_buffer_and_trigger:
ad_sd_cleanup_buffer_and_trigger(indio_dev);
error_disable_reg:
- if (!IS_ERR(st->reg))
- regulator_disable(st->reg);
+ regulator_disable(st->reg);
return ret;
}
@@ -236,8 +237,7 @@ static int ad7780_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
ad_sd_cleanup_buffer_and_trigger(indio_dev);
- if (!IS_ERR(st->reg))
- regulator_disable(st->reg);
+ regulator_disable(st->reg);
return 0;
}
diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c
index 5e8115b01011..72551f827382 100644
--- a/drivers/staging/iio/adc/ad7816.c
+++ b/drivers/staging/iio/adc/ad7816.c
@@ -327,7 +327,7 @@ static struct attribute *ad7816_event_attributes[] = {
NULL,
};
-static struct attribute_group ad7816_event_attribute_group = {
+static const struct attribute_group ad7816_event_attribute_group = {
.attrs = ad7816_event_attributes,
.name = "events",
};
diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c
index 3faffe59c933..a7d90c8bac5e 100644
--- a/drivers/staging/iio/addac/adt7316.c
+++ b/drivers/staging/iio/addac/adt7316.c
@@ -2039,7 +2039,7 @@ static struct attribute *adt7316_event_attributes[] = {
NULL,
};
-static struct attribute_group adt7316_event_attribute_group = {
+static const struct attribute_group adt7316_event_attribute_group = {
.attrs = adt7316_event_attributes,
.name = "events",
};
@@ -2060,7 +2060,7 @@ static struct attribute *adt7516_event_attributes[] = {
NULL,
};
-static struct attribute_group adt7516_event_attribute_group = {
+static const struct attribute_group adt7516_event_attribute_group = {
.attrs = adt7516_event_attributes,
.name = "events",
};
diff --git a/drivers/staging/iio/cdc/ad7150.c b/drivers/staging/iio/cdc/ad7150.c
index 5578a077fcfb..6998c3ddfb6a 100644
--- a/drivers/staging/iio/cdc/ad7150.c
+++ b/drivers/staging/iio/cdc/ad7150.c
@@ -562,7 +562,7 @@ static struct attribute *ad7150_event_attributes[] = {
NULL,
};
-static struct attribute_group ad7150_event_attribute_group = {
+static const struct attribute_group ad7150_event_attribute_group = {
.attrs = ad7150_event_attributes,
.name = "events",
};
diff --git a/drivers/staging/iio/cdc/ad7152.c b/drivers/staging/iio/cdc/ad7152.c
index 485d0a5af53c..b91b50f345bd 100644
--- a/drivers/staging/iio/cdc/ad7152.c
+++ b/drivers/staging/iio/cdc/ad7152.c
@@ -89,6 +89,7 @@ struct ad7152_chip_info {
*/
u8 filter_rate_setup;
u8 setup[2];
+ struct mutex state_lock; /* protect hardware state */
};
static inline ssize_t ad7152_start_calib(struct device *dev,
@@ -115,10 +116,10 @@ static inline ssize_t ad7152_start_calib(struct device *dev,
else
regval |= AD7152_CONF_CH2EN;
- mutex_lock(&indio_dev->mlock);
+ mutex_lock(&chip->state_lock);
ret = i2c_smbus_write_byte_data(chip->client, AD7152_REG_CFG, regval);
if (ret < 0) {
- mutex_unlock(&indio_dev->mlock);
+ mutex_unlock(&chip->state_lock);
return ret;
}
@@ -126,14 +127,15 @@ static inline ssize_t ad7152_start_calib(struct device *dev,
mdelay(20);
ret = i2c_smbus_read_byte_data(chip->client, AD7152_REG_CFG);
if (ret < 0) {
- mutex_unlock(&indio_dev->mlock);
+ mutex_unlock(&chip->state_lock);
return ret;
}
} while ((ret == regval) && timeout--);
- mutex_unlock(&indio_dev->mlock);
+ mutex_unlock(&chip->state_lock);
return len;
}
+
static ssize_t ad7152_start_offset_calib(struct device *dev,
struct device_attribute *attr,
const char *buf,
@@ -142,6 +144,7 @@ static ssize_t ad7152_start_offset_calib(struct device *dev,
return ad7152_start_calib(dev, attr, buf, len,
AD7152_CONF_MODE_OFFS_CAL);
}
+
static ssize_t ad7152_start_gain_calib(struct device *dev,
struct device_attribute *attr,
const char *buf,
@@ -165,63 +168,12 @@ static const unsigned char ad7152_filter_rate_table[][2] = {
{200, 5 + 1}, {50, 20 + 1}, {20, 50 + 1}, {17, 60 + 1},
};
-static ssize_t ad7152_show_filter_rate_setup(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct ad7152_chip_info *chip = iio_priv(indio_dev);
-
- return sprintf(buf, "%d\n",
- ad7152_filter_rate_table[chip->filter_rate_setup][0]);
-}
-
-static ssize_t ad7152_store_filter_rate_setup(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct ad7152_chip_info *chip = iio_priv(indio_dev);
- u8 data;
- int ret, i;
-
- ret = kstrtou8(buf, 10, &data);
- if (ret < 0)
- return ret;
-
- for (i = 0; i < ARRAY_SIZE(ad7152_filter_rate_table); i++)
- if (data >= ad7152_filter_rate_table[i][0])
- break;
-
- if (i >= ARRAY_SIZE(ad7152_filter_rate_table))
- i = ARRAY_SIZE(ad7152_filter_rate_table) - 1;
-
- mutex_lock(&indio_dev->mlock);
- ret = i2c_smbus_write_byte_data(chip->client,
- AD7152_REG_CFG2, AD7152_CFG2_OSR(i));
- if (ret < 0) {
- mutex_unlock(&indio_dev->mlock);
- return ret;
- }
-
- chip->filter_rate_setup = i;
- mutex_unlock(&indio_dev->mlock);
-
- return len;
-}
-
-static IIO_DEV_ATTR_SAMP_FREQ(S_IRUGO | S_IWUSR,
- ad7152_show_filter_rate_setup,
- ad7152_store_filter_rate_setup);
-
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("200 50 20 17");
static IIO_CONST_ATTR(in_capacitance_scale_available,
"0.000061050 0.000030525 0.000015263 0.000007631");
static struct attribute *ad7152_attributes[] = {
- &iio_dev_attr_sampling_frequency.dev_attr.attr,
&iio_dev_attr_in_capacitance0_calibbias_calibration.dev_attr.attr,
&iio_dev_attr_in_capacitance1_calibbias_calibration.dev_attr.attr,
&iio_dev_attr_in_capacitance0_calibscale_calibration.dev_attr.attr,
@@ -247,6 +199,51 @@ static const int ad7152_scale_table[] = {
30525, 7631, 15263, 61050
};
+/**
+ * read_raw handler for IIO_CHAN_INFO_SAMP_FREQ
+ *
+ * lock must be held
+ **/
+static int ad7152_read_raw_samp_freq(struct device *dev, int *val)
+{
+ struct ad7152_chip_info *chip = iio_priv(dev_to_iio_dev(dev));
+
+ *val = ad7152_filter_rate_table[chip->filter_rate_setup][0];
+
+ return 0;
+}
+
+/**
+ * write_raw handler for IIO_CHAN_INFO_SAMP_FREQ
+ *
+ * lock must be held
+ **/
+static int ad7152_write_raw_samp_freq(struct device *dev, int val)
+{
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct ad7152_chip_info *chip = iio_priv(indio_dev);
+ int ret, i;
+
+ for (i = 0; i < ARRAY_SIZE(ad7152_filter_rate_table); i++)
+ if (val >= ad7152_filter_rate_table[i][0])
+ break;
+
+ if (i >= ARRAY_SIZE(ad7152_filter_rate_table))
+ i = ARRAY_SIZE(ad7152_filter_rate_table) - 1;
+
+ mutex_lock(&chip->state_lock);
+ ret = i2c_smbus_write_byte_data(chip->client,
+ AD7152_REG_CFG2, AD7152_CFG2_OSR(i));
+ if (ret < 0) {
+ mutex_unlock(&chip->state_lock);
+ return ret;
+ }
+
+ chip->filter_rate_setup = i;
+ mutex_unlock(&chip->state_lock);
+
+ return ret;
+}
static int ad7152_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int val,
@@ -256,7 +253,7 @@ static int ad7152_write_raw(struct iio_dev *indio_dev,
struct ad7152_chip_info *chip = iio_priv(indio_dev);
int ret, i;
- mutex_lock(&indio_dev->mlock);
+ mutex_lock(&chip->state_lock);
switch (mask) {
case IIO_CHAN_INFO_CALIBSCALE:
@@ -309,14 +306,26 @@ static int ad7152_write_raw(struct iio_dev *indio_dev,
ret = 0;
break;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ if (val2) {
+ ret = -EINVAL;
+ goto out;
+ }
+ ret = ad7152_write_raw_samp_freq(&indio_dev->dev, val);
+ if (ret < 0)
+ goto out;
+
+ ret = 0;
+ break;
default:
ret = -EINVAL;
}
out:
- mutex_unlock(&indio_dev->mlock);
+ mutex_unlock(&chip->state_lock);
return ret;
}
+
static int ad7152_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2,
@@ -326,7 +335,7 @@ static int ad7152_read_raw(struct iio_dev *indio_dev,
int ret;
u8 regval = 0;
- mutex_lock(&indio_dev->mlock);
+ mutex_lock(&chip->state_lock);
switch (mask) {
case IIO_CHAN_INFO_RAW:
@@ -403,11 +412,18 @@ static int ad7152_read_raw(struct iio_dev *indio_dev,
ret = IIO_VAL_INT_PLUS_NANO;
break;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ ret = ad7152_read_raw_samp_freq(&indio_dev->dev, val);
+ if (ret < 0)
+ goto out;
+
+ ret = IIO_VAL_INT;
+ break;
default:
ret = -EINVAL;
}
out:
- mutex_unlock(&indio_dev->mlock);
+ mutex_unlock(&chip->state_lock);
return ret;
}
@@ -440,6 +456,7 @@ static const struct iio_chan_spec ad7152_channels[] = {
BIT(IIO_CHAN_INFO_CALIBSCALE) |
BIT(IIO_CHAN_INFO_CALIBBIAS) |
BIT(IIO_CHAN_INFO_SCALE),
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
}, {
.type = IIO_CAPACITANCE,
.differential = 1,
@@ -450,6 +467,7 @@ static const struct iio_chan_spec ad7152_channels[] = {
BIT(IIO_CHAN_INFO_CALIBSCALE) |
BIT(IIO_CHAN_INFO_CALIBBIAS) |
BIT(IIO_CHAN_INFO_SCALE),
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
}, {
.type = IIO_CAPACITANCE,
.indexed = 1,
@@ -458,6 +476,7 @@ static const struct iio_chan_spec ad7152_channels[] = {
BIT(IIO_CHAN_INFO_CALIBSCALE) |
BIT(IIO_CHAN_INFO_CALIBBIAS) |
BIT(IIO_CHAN_INFO_SCALE),
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
}, {
.type = IIO_CAPACITANCE,
.differential = 1,
@@ -468,8 +487,10 @@ static const struct iio_chan_spec ad7152_channels[] = {
BIT(IIO_CHAN_INFO_CALIBSCALE) |
BIT(IIO_CHAN_INFO_CALIBBIAS) |
BIT(IIO_CHAN_INFO_SCALE),
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
}
};
+
/*
* device probe and remove
*/
@@ -489,6 +510,7 @@ static int ad7152_probe(struct i2c_client *client,
i2c_set_clientdata(client, indio_dev);
chip->client = client;
+ mutex_init(&chip->state_lock);
/* Establish that the iio_dev is a child of the i2c device */
indio_dev->name = id->name;
diff --git a/drivers/staging/iio/cdc/ad7746.c b/drivers/staging/iio/cdc/ad7746.c
index 5771d4ee8ef1..81f8b9ee1120 100644
--- a/drivers/staging/iio/cdc/ad7746.c
+++ b/drivers/staging/iio/cdc/ad7746.c
@@ -70,8 +70,10 @@
#define AD7746_EXCSETUP_EXCLVL(x) (((x) & 0x3) << 0)
/* Config Register Bit Designations (AD7746_REG_CFG) */
-#define AD7746_CONF_VTFS(x) ((x) << 6)
-#define AD7746_CONF_CAPFS(x) ((x) << 3)
+#define AD7746_CONF_VTFS_SHIFT 6
+#define AD7746_CONF_CAPFS_SHIFT 3
+#define AD7746_CONF_VTFS_MASK GENMASK(7, 6)
+#define AD7746_CONF_CAPFS_MASK GENMASK(5, 3)
#define AD7746_CONF_MODE_IDLE (0 << 0)
#define AD7746_CONF_MODE_CONT_CONV (1 << 0)
#define AD7746_CONF_MODE_SINGLE_CONV (2 << 0)
@@ -122,7 +124,8 @@ static const struct iio_chan_spec ad7746_channels[] = {
.indexed = 1,
.channel = 0,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
- .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |
+ BIT(IIO_CHAN_INFO_SAMP_FREQ),
.address = AD7746_REG_VT_DATA_HIGH << 8 |
AD7746_VTSETUP_VTMD_EXT_VIN,
},
@@ -132,7 +135,8 @@ static const struct iio_chan_spec ad7746_channels[] = {
.channel = 1,
.extend_name = "supply",
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
- .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |
+ BIT(IIO_CHAN_INFO_SAMP_FREQ),
.address = AD7746_REG_VT_DATA_HIGH << 8 |
AD7746_VTSETUP_VTMD_VDD_MON,
},
@@ -159,7 +163,7 @@ static const struct iio_chan_spec ad7746_channels[] = {
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_CALIBSCALE) | BIT(IIO_CHAN_INFO_OFFSET),
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBBIAS) |
- BIT(IIO_CHAN_INFO_SCALE),
+ BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_SAMP_FREQ),
.address = AD7746_REG_CAP_DATA_HIGH << 8,
},
[CIN1_DIFF] = {
@@ -171,7 +175,7 @@ static const struct iio_chan_spec ad7746_channels[] = {
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_CALIBSCALE) | BIT(IIO_CHAN_INFO_OFFSET),
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBBIAS) |
- BIT(IIO_CHAN_INFO_SCALE),
+ BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_SAMP_FREQ),
.address = AD7746_REG_CAP_DATA_HIGH << 8 |
AD7746_CAPSETUP_CAPDIFF
},
@@ -182,7 +186,7 @@ static const struct iio_chan_spec ad7746_channels[] = {
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_CALIBSCALE) | BIT(IIO_CHAN_INFO_OFFSET),
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBBIAS) |
- BIT(IIO_CHAN_INFO_SCALE),
+ BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_SAMP_FREQ),
.address = AD7746_REG_CAP_DATA_HIGH << 8 |
AD7746_CAPSETUP_CIN2,
},
@@ -195,7 +199,7 @@ static const struct iio_chan_spec ad7746_channels[] = {
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_CALIBSCALE) | BIT(IIO_CHAN_INFO_OFFSET),
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBBIAS) |
- BIT(IIO_CHAN_INFO_SCALE),
+ BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_SAMP_FREQ),
.address = AD7746_REG_CAP_DATA_HIGH << 8 |
AD7746_CAPSETUP_CAPDIFF | AD7746_CAPSETUP_CIN2,
}
@@ -215,15 +219,16 @@ static int ad7746_select_channel(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan)
{
struct ad7746_chip_info *chip = iio_priv(indio_dev);
- int ret, delay;
+ int ret, delay, idx;
u8 vt_setup, cap_setup;
switch (chan->type) {
case IIO_CAPACITANCE:
cap_setup = (chan->address & 0xFF) | AD7746_CAPSETUP_CAPEN;
vt_setup = chip->vt_setup & ~AD7746_VTSETUP_VTEN;
- delay = ad7746_cap_filter_rate_table[(chip->config >> 3) &
- 0x7][1];
+ idx = (chip->config & AD7746_CONF_CAPFS_MASK) >>
+ AD7746_CONF_CAPFS_SHIFT;
+ delay = ad7746_cap_filter_rate_table[idx][1];
if (chip->capdac_set != chan->channel) {
ret = i2c_smbus_write_byte_data(chip->client,
@@ -244,8 +249,9 @@ static int ad7746_select_channel(struct iio_dev *indio_dev,
case IIO_TEMP:
vt_setup = (chan->address & 0xFF) | AD7746_VTSETUP_VTEN;
cap_setup = chip->cap_setup & ~AD7746_CAPSETUP_CAPEN;
- delay = ad7746_cap_filter_rate_table[(chip->config >> 6) &
- 0x3][1];
+ idx = (chip->config & AD7746_CONF_VTFS_MASK) >>
+ AD7746_CONF_VTFS_SHIFT;
+ delay = ad7746_cap_filter_rate_table[idx][1];
break;
default:
return -EINVAL;
@@ -355,101 +361,47 @@ static IIO_DEVICE_ATTR(in_capacitance1_calibscale_calibration,
static IIO_DEVICE_ATTR(in_voltage0_calibscale_calibration,
S_IWUSR, NULL, ad7746_start_gain_calib, VIN);
-static ssize_t ad7746_show_cap_filter_rate_setup(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+static int ad7746_store_cap_filter_rate_setup(struct ad7746_chip_info *chip,
+ int val)
{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct ad7746_chip_info *chip = iio_priv(indio_dev);
-
- return sprintf(buf, "%d\n", ad7746_cap_filter_rate_table[
- (chip->config >> 3) & 0x7][0]);
-}
-
-static ssize_t ad7746_store_cap_filter_rate_setup(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct ad7746_chip_info *chip = iio_priv(indio_dev);
- u8 data;
- int ret, i;
-
- ret = kstrtou8(buf, 10, &data);
- if (ret < 0)
- return ret;
+ int i;
for (i = 0; i < ARRAY_SIZE(ad7746_cap_filter_rate_table); i++)
- if (data >= ad7746_cap_filter_rate_table[i][0])
+ if (val >= ad7746_cap_filter_rate_table[i][0])
break;
if (i >= ARRAY_SIZE(ad7746_cap_filter_rate_table))
i = ARRAY_SIZE(ad7746_cap_filter_rate_table) - 1;
- mutex_lock(&indio_dev->mlock);
- chip->config &= ~AD7746_CONF_CAPFS(0x7);
- chip->config |= AD7746_CONF_CAPFS(i);
- mutex_unlock(&indio_dev->mlock);
+ chip->config &= ~AD7746_CONF_CAPFS_MASK;
+ chip->config |= i << AD7746_CONF_CAPFS_SHIFT;
- return len;
+ return 0;
}
-static ssize_t ad7746_show_vt_filter_rate_setup(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+static int ad7746_store_vt_filter_rate_setup(struct ad7746_chip_info *chip,
+ int val)
{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct ad7746_chip_info *chip = iio_priv(indio_dev);
-
- return sprintf(buf, "%d\n", ad7746_vt_filter_rate_table[
- (chip->config >> 6) & 0x3][0]);
-}
-
-static ssize_t ad7746_store_vt_filter_rate_setup(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct ad7746_chip_info *chip = iio_priv(indio_dev);
- u8 data;
- int ret, i;
-
- ret = kstrtou8(buf, 10, &data);
- if (ret < 0)
- return ret;
+ int i;
for (i = 0; i < ARRAY_SIZE(ad7746_vt_filter_rate_table); i++)
- if (data >= ad7746_vt_filter_rate_table[i][0])
+ if (val >= ad7746_vt_filter_rate_table[i][0])
break;
if (i >= ARRAY_SIZE(ad7746_vt_filter_rate_table))
i = ARRAY_SIZE(ad7746_vt_filter_rate_table) - 1;
- mutex_lock(&indio_dev->mlock);
- chip->config &= ~AD7746_CONF_VTFS(0x3);
- chip->config |= AD7746_CONF_VTFS(i);
- mutex_unlock(&indio_dev->mlock);
+ chip->config &= ~AD7746_CONF_VTFS_MASK;
+ chip->config |= i << AD7746_CONF_VTFS_SHIFT;
- return len;
+ return 0;
}
-static IIO_DEVICE_ATTR(in_capacitance_sampling_frequency,
- S_IRUGO | S_IWUSR, ad7746_show_cap_filter_rate_setup,
- ad7746_store_cap_filter_rate_setup, 0);
-
-static IIO_DEVICE_ATTR(in_voltage_sampling_frequency,
- S_IRUGO | S_IWUSR, ad7746_show_vt_filter_rate_setup,
- ad7746_store_vt_filter_rate_setup, 0);
-
static IIO_CONST_ATTR(in_voltage_sampling_frequency_available, "50 31 16 8");
static IIO_CONST_ATTR(in_capacitance_sampling_frequency_available,
"91 84 50 26 16 13 11 9");
static struct attribute *ad7746_attributes[] = {
- &iio_dev_attr_in_capacitance_sampling_frequency.dev_attr.attr,
- &iio_dev_attr_in_voltage_sampling_frequency.dev_attr.attr,
&iio_dev_attr_in_capacitance0_calibbias_calibration.dev_attr.attr,
&iio_dev_attr_in_capacitance0_calibscale_calibration.dev_attr.attr,
&iio_dev_attr_in_capacitance1_calibscale_calibration.dev_attr.attr,
@@ -547,6 +499,23 @@ static int ad7746_write_raw(struct iio_dev *indio_dev,
ret = 0;
break;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ if (val2) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ switch (chan->type) {
+ case IIO_CAPACITANCE:
+ ret = ad7746_store_cap_filter_rate_setup(chip, val);
+ break;
+ case IIO_VOLTAGE:
+ ret = ad7746_store_vt_filter_rate_setup(chip, val);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ break;
default:
ret = -EINVAL;
}
@@ -562,7 +531,7 @@ static int ad7746_read_raw(struct iio_dev *indio_dev,
long mask)
{
struct ad7746_chip_info *chip = iio_priv(indio_dev);
- int ret, delay;
+ int ret, delay, idx;
u8 regval, reg;
mutex_lock(&indio_dev->mlock);
@@ -667,6 +636,24 @@ static int ad7746_read_raw(struct iio_dev *indio_dev,
}
break;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ switch (chan->type) {
+ case IIO_CAPACITANCE:
+ idx = (chip->config & AD7746_CONF_CAPFS_MASK) >>
+ AD7746_CONF_CAPFS_SHIFT;
+ *val = ad7746_cap_filter_rate_table[idx][0];
+ ret = IIO_VAL_INT;
+ break;
+ case IIO_VOLTAGE:
+ idx = (chip->config & AD7746_CONF_VTFS_MASK) >>
+ AD7746_CONF_VTFS_SHIFT;
+ *val = ad7746_vt_filter_rate_table[idx][0];
+ ret = IIO_VAL_INT;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ break;
default:
ret = -EINVAL;
}
diff --git a/drivers/staging/iio/frequency/ad9832.c b/drivers/staging/iio/frequency/ad9832.c
index 358400b22d33..a5b2f068168d 100644
--- a/drivers/staging/iio/frequency/ad9832.c
+++ b/drivers/staging/iio/frequency/ad9832.c
@@ -204,7 +204,6 @@ static int ad9832_probe(struct spi_device *spi)
struct ad9832_platform_data *pdata = dev_get_platdata(&spi->dev);
struct iio_dev *indio_dev;
struct ad9832_state *st;
- struct regulator *reg;
int ret;
if (!pdata) {
@@ -212,21 +211,35 @@ static int ad9832_probe(struct spi_device *spi)
return -ENODEV;
}
- reg = devm_regulator_get(&spi->dev, "vcc");
- if (!IS_ERR(reg)) {
- ret = regulator_enable(reg);
- if (ret)
- return ret;
- }
-
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
- if (!indio_dev) {
- ret = -ENOMEM;
- goto error_disable_reg;
- }
+ if (!indio_dev)
+ return -ENOMEM;
+
spi_set_drvdata(spi, indio_dev);
st = iio_priv(indio_dev);
- st->reg = reg;
+
+ st->avdd = devm_regulator_get(&spi->dev, "avdd");
+ if (IS_ERR(st->avdd))
+ return PTR_ERR(st->avdd);
+
+ ret = regulator_enable(st->avdd);
+ if (ret) {
+ dev_err(&spi->dev, "Failed to enable specified AVDD supply\n");
+ return ret;
+ }
+
+ st->dvdd = devm_regulator_get(&spi->dev, "dvdd");
+ if (IS_ERR(st->dvdd)) {
+ ret = PTR_ERR(st->dvdd);
+ goto error_disable_avdd;
+ }
+
+ ret = regulator_enable(st->dvdd);
+ if (ret) {
+ dev_err(&spi->dev, "Failed to enable specified DVDD supply\n");
+ goto error_disable_avdd;
+ }
+
st->mclk = pdata->mclk;
st->spi = spi;
@@ -277,42 +290,43 @@ static int ad9832_probe(struct spi_device *spi)
ret = spi_sync(st->spi, &st->msg);
if (ret) {
dev_err(&spi->dev, "device init failed\n");
- goto error_disable_reg;
+ goto error_disable_dvdd;
}
ret = ad9832_write_frequency(st, AD9832_FREQ0HM, pdata->freq0);
if (ret)
- goto error_disable_reg;
+ goto error_disable_dvdd;
ret = ad9832_write_frequency(st, AD9832_FREQ1HM, pdata->freq1);
if (ret)
- goto error_disable_reg;
+ goto error_disable_dvdd;
ret = ad9832_write_phase(st, AD9832_PHASE0H, pdata->phase0);
if (ret)
- goto error_disable_reg;
+ goto error_disable_dvdd;
ret = ad9832_write_phase(st, AD9832_PHASE1H, pdata->phase1);
if (ret)
- goto error_disable_reg;
+ goto error_disable_dvdd;
ret = ad9832_write_phase(st, AD9832_PHASE2H, pdata->phase2);
if (ret)
- goto error_disable_reg;
+ goto error_disable_dvdd;
ret = ad9832_write_phase(st, AD9832_PHASE3H, pdata->phase3);
if (ret)
- goto error_disable_reg;
+ goto error_disable_dvdd;
ret = iio_device_register(indio_dev);
if (ret)
- goto error_disable_reg;
+ goto error_disable_dvdd;
return 0;
-error_disable_reg:
- if (!IS_ERR(reg))
- regulator_disable(reg);
+error_disable_dvdd:
+ regulator_disable(st->dvdd);
+error_disable_avdd:
+ regulator_disable(st->avdd);
return ret;
}
@@ -323,8 +337,8 @@ static int ad9832_remove(struct spi_device *spi)
struct ad9832_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
- if (!IS_ERR(st->reg))
- regulator_disable(st->reg);
+ regulator_disable(st->dvdd);
+ regulator_disable(st->avdd);
return 0;
}
diff --git a/drivers/staging/iio/frequency/ad9832.h b/drivers/staging/iio/frequency/ad9832.h
index d32323b46be6..1b08b04482a4 100644
--- a/drivers/staging/iio/frequency/ad9832.h
+++ b/drivers/staging/iio/frequency/ad9832.h
@@ -58,7 +58,8 @@
/**
* struct ad9832_state - driver instance specific data
* @spi: spi_device
- * @reg: supply regulator
+ * @avdd: supply regulator for the analog section
+ * @dvdd: supply regulator for the digital section
* @mclk: external master clock
* @ctrl_fp: cached frequency/phase control word
* @ctrl_ss: cached sync/selsrc control word
@@ -76,7 +77,8 @@
struct ad9832_state {
struct spi_device *spi;
- struct regulator *reg;
+ struct regulator *avdd;
+ struct regulator *dvdd;
unsigned long mclk;
unsigned short ctrl_fp;
unsigned short ctrl_ss;
diff --git a/drivers/staging/iio/frequency/ad9834.c b/drivers/staging/iio/frequency/ad9834.c
index 6366216e4f37..19216af1dfc9 100644
--- a/drivers/staging/iio/frequency/ad9834.c
+++ b/drivers/staging/iio/frequency/ad9834.c
@@ -329,11 +329,14 @@ static int ad9834_probe(struct spi_device *spi)
return -ENODEV;
}
- reg = devm_regulator_get(&spi->dev, "vcc");
- if (!IS_ERR(reg)) {
- ret = regulator_enable(reg);
- if (ret)
- return ret;
+ reg = devm_regulator_get(&spi->dev, "avdd");
+ if (IS_ERR(reg))
+ return PTR_ERR(reg);
+
+ ret = regulator_enable(reg);
+ if (ret) {
+ dev_err(&spi->dev, "Failed to enable specified AVDD supply\n");
+ return ret;
}
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
@@ -416,8 +419,7 @@ static int ad9834_probe(struct spi_device *spi)
return 0;
error_disable_reg:
- if (!IS_ERR(reg))
- regulator_disable(reg);
+ regulator_disable(reg);
return ret;
}
@@ -428,8 +430,7 @@ static int ad9834_remove(struct spi_device *spi)
struct ad9834_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
- if (!IS_ERR(st->reg))
- regulator_disable(st->reg);
+ regulator_disable(st->reg);
return 0;
}
diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c
index 3892a7470410..944789843938 100644
--- a/drivers/staging/iio/impedance-analyzer/ad5933.c
+++ b/drivers/staging/iio/impedance-analyzer/ad5933.c
@@ -726,13 +726,16 @@ static int ad5933_probe(struct i2c_client *client,
if (!pdata)
pdata = &ad5933_default_pdata;
- st->reg = devm_regulator_get(&client->dev, "vcc");
- if (!IS_ERR(st->reg)) {
- ret = regulator_enable(st->reg);
- if (ret)
- return ret;
- voltage_uv = regulator_get_voltage(st->reg);
+ st->reg = devm_regulator_get(&client->dev, "vdd");
+ if (IS_ERR(st->reg))
+ return PTR_ERR(st->reg);
+
+ ret = regulator_enable(st->reg);
+ if (ret) {
+ dev_err(&client->dev, "Failed to enable specified VDD supply\n");
+ return ret;
}
+ voltage_uv = regulator_get_voltage(st->reg);
if (voltage_uv)
st->vref_mv = voltage_uv / 1000;
@@ -775,8 +778,7 @@ static int ad5933_probe(struct i2c_client *client,
error_unreg_ring:
iio_kfifo_free(indio_dev->buffer);
error_disable_reg:
- if (!IS_ERR(st->reg))
- regulator_disable(st->reg);
+ regulator_disable(st->reg);
return ret;
}
@@ -788,8 +790,7 @@ static int ad5933_remove(struct i2c_client *client)
iio_device_unregister(indio_dev);
iio_kfifo_free(indio_dev->buffer);
- if (!IS_ERR(st->reg))
- regulator_disable(st->reg);
+ regulator_disable(st->reg);
return 0;
}
diff --git a/drivers/staging/iio/light/Kconfig b/drivers/staging/iio/light/Kconfig
index ca8d6e66c899..4fbf6298c0f3 100644
--- a/drivers/staging/iio/light/Kconfig
+++ b/drivers/staging/iio/light/Kconfig
@@ -3,18 +3,6 @@
#
menu "Light sensors"
-config SENSORS_ISL29018
- tristate "ISL 29018 light and proximity sensor"
- depends on I2C
- select REGMAP_I2C
- default n
- help
- If you say yes here you get support for ambient light sensing and
- proximity infrared sensing from Intersil ISL29018.
- This driver will provide the measurements of ambient light intensity
- in lux, proximity infrared sensing and normal infrared sensing.
- Data from sensor is accessible via sysfs.
-
config SENSORS_ISL29028
tristate "Intersil ISL29028 Concurrent Light and Proximity Sensor"
depends on I2C
@@ -25,13 +13,6 @@ config SENSORS_ISL29028
Proximity value via iio. The ISL29028 provides the concurrent sensing
of ambient light and proximity.
-config TSL2583
- tristate "TAOS TSL2580, TSL2581 and TSL2583 light-to-digital converters"
- depends on I2C
- help
- Provides support for the TAOS tsl2580, tsl2581 and tsl2583 devices.
- Access ALS data via iio, sysfs.
-
config TSL2x7x
tristate "TAOS TSL/TMD2x71 and TSL/TMD2x72 Family of light and proximity sensors"
depends on I2C
diff --git a/drivers/staging/iio/light/Makefile b/drivers/staging/iio/light/Makefile
index 9960fdf7c15b..f8693e9fdc94 100644
--- a/drivers/staging/iio/light/Makefile
+++ b/drivers/staging/iio/light/Makefile
@@ -2,7 +2,5 @@
# Makefile for industrial I/O Light sensors
#
-obj-$(CONFIG_SENSORS_ISL29018) += isl29018.o
obj-$(CONFIG_SENSORS_ISL29028) += isl29028.o
-obj-$(CONFIG_TSL2583) += tsl2583.o
obj-$(CONFIG_TSL2x7x) += tsl2x7x_core.o
diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c
deleted file mode 100644
index a767a43c995c..000000000000
--- a/drivers/staging/iio/light/isl29018.c
+++ /dev/null
@@ -1,834 +0,0 @@
-/*
- * A iio driver for the light sensor ISL 29018/29023/29035.
- *
- * IIO driver for monitoring ambient light intensity in luxi, proximity
- * sensing and infrared sensing.
- *
- * Copyright (c) 2010, NVIDIA Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- */
-
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/err.h>
-#include <linux/mutex.h>
-#include <linux/delay.h>
-#include <linux/regmap.h>
-#include <linux/slab.h>
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-#include <linux/acpi.h>
-
-#define ISL29018_CONV_TIME_MS 100
-
-#define ISL29018_REG_ADD_COMMAND1 0x00
-#define ISL29018_CMD1_OPMODE_SHIFT 5
-#define ISL29018_CMD1_OPMODE_MASK (7 << ISL29018_CMD1_OPMODE_SHIFT)
-#define ISL29018_CMD1_OPMODE_POWER_DOWN 0
-#define ISL29018_CMD1_OPMODE_ALS_ONCE 1
-#define ISL29018_CMD1_OPMODE_IR_ONCE 2
-#define ISL29018_CMD1_OPMODE_PROX_ONCE 3
-
-#define ISL29018_REG_ADD_COMMAND2 0x01
-#define ISL29018_CMD2_RESOLUTION_SHIFT 2
-#define ISL29018_CMD2_RESOLUTION_MASK (0x3 << ISL29018_CMD2_RESOLUTION_SHIFT)
-
-#define ISL29018_CMD2_RANGE_SHIFT 0
-#define ISL29018_CMD2_RANGE_MASK (0x3 << ISL29018_CMD2_RANGE_SHIFT)
-
-#define ISL29018_CMD2_SCHEME_SHIFT 7
-#define ISL29018_CMD2_SCHEME_MASK (0x1 << ISL29018_CMD2_SCHEME_SHIFT)
-
-#define ISL29018_REG_ADD_DATA_LSB 0x02
-#define ISL29018_REG_ADD_DATA_MSB 0x03
-
-#define ISL29018_REG_TEST 0x08
-#define ISL29018_TEST_SHIFT 0
-#define ISL29018_TEST_MASK (0xFF << ISL29018_TEST_SHIFT)
-
-#define ISL29035_REG_DEVICE_ID 0x0F
-#define ISL29035_DEVICE_ID_SHIFT 0x03
-#define ISL29035_DEVICE_ID_MASK (0x7 << ISL29035_DEVICE_ID_SHIFT)
-#define ISL29035_DEVICE_ID 0x5
-#define ISL29035_BOUT_SHIFT 0x07
-#define ISL29035_BOUT_MASK (0x01 << ISL29035_BOUT_SHIFT)
-
-#define ISL29018_INT_TIME_AVAIL "0.090000 0.005630 0.000351 0.000021"
-#define ISL29023_INT_TIME_AVAIL "0.090000 0.005600 0.000352 0.000022"
-#define ISL29035_INT_TIME_AVAIL "0.105000 0.006500 0.000410 0.000025"
-
-static const char * const int_time_avail[] = {
- ISL29018_INT_TIME_AVAIL,
- ISL29023_INT_TIME_AVAIL,
- ISL29035_INT_TIME_AVAIL,
-};
-
-enum isl29018_int_time {
- ISL29018_INT_TIME_16,
- ISL29018_INT_TIME_12,
- ISL29018_INT_TIME_8,
- ISL29018_INT_TIME_4,
-};
-
-static const unsigned int isl29018_int_utimes[3][4] = {
- {90000, 5630, 351, 21},
- {90000, 5600, 352, 22},
- {105000, 6500, 410, 25},
-};
-
-static const struct isl29018_scale {
- unsigned int scale;
- unsigned int uscale;
-} isl29018_scales[4][4] = {
- { {0, 15258}, {0, 61035}, {0, 244140}, {0, 976562} },
- { {0, 244140}, {0, 976562}, {3, 906250}, {15, 625000} },
- { {3, 906250}, {15, 625000}, {62, 500000}, {250, 0} },
- { {62, 500000}, {250, 0}, {1000, 0}, {4000, 0} }
-};
-
-struct isl29018_chip {
- struct regmap *regmap;
- struct mutex lock;
- int type;
- unsigned int calibscale;
- unsigned int ucalibscale;
- unsigned int int_time;
- struct isl29018_scale scale;
- int prox_scheme;
- bool suspended;
-};
-
-static int isl29018_set_integration_time(struct isl29018_chip *chip,
- unsigned int utime)
-{
- int i, ret;
- unsigned int int_time, new_int_time;
-
- for (i = 0; i < ARRAY_SIZE(isl29018_int_utimes[chip->type]); ++i) {
- if (utime == isl29018_int_utimes[chip->type][i]) {
- new_int_time = i;
- break;
- }
- }
-
- if (i >= ARRAY_SIZE(isl29018_int_utimes[chip->type]))
- return -EINVAL;
-
- ret = regmap_update_bits(chip->regmap, ISL29018_REG_ADD_COMMAND2,
- ISL29018_CMD2_RESOLUTION_MASK,
- i << ISL29018_CMD2_RESOLUTION_SHIFT);
- if (ret < 0)
- return ret;
-
- /* Keep the same range when integration time changes */
- int_time = chip->int_time;
- for (i = 0; i < ARRAY_SIZE(isl29018_scales[int_time]); ++i) {
- if (chip->scale.scale == isl29018_scales[int_time][i].scale &&
- chip->scale.uscale == isl29018_scales[int_time][i].uscale) {
- chip->scale = isl29018_scales[new_int_time][i];
- break;
- }
- }
- chip->int_time = new_int_time;
-
- return 0;
-}
-
-static int isl29018_set_scale(struct isl29018_chip *chip, int scale, int uscale)
-{
- int i, ret;
- struct isl29018_scale new_scale;
-
- for (i = 0; i < ARRAY_SIZE(isl29018_scales[chip->int_time]); ++i) {
- if (scale == isl29018_scales[chip->int_time][i].scale &&
- uscale == isl29018_scales[chip->int_time][i].uscale) {
- new_scale = isl29018_scales[chip->int_time][i];
- break;
- }
- }
-
- if (i >= ARRAY_SIZE(isl29018_scales[chip->int_time]))
- return -EINVAL;
-
- ret = regmap_update_bits(chip->regmap, ISL29018_REG_ADD_COMMAND2,
- ISL29018_CMD2_RANGE_MASK,
- i << ISL29018_CMD2_RANGE_SHIFT);
- if (ret < 0)
- return ret;
-
- chip->scale = new_scale;
-
- return 0;
-}
-
-static int isl29018_read_sensor_input(struct isl29018_chip *chip, int mode)
-{
- int status;
- unsigned int lsb;
- unsigned int msb;
- struct device *dev = regmap_get_device(chip->regmap);
-
- /* Set mode */
- status = regmap_write(chip->regmap, ISL29018_REG_ADD_COMMAND1,
- mode << ISL29018_CMD1_OPMODE_SHIFT);
- if (status) {
- dev_err(dev,
- "Error in setting operating mode err %d\n", status);
- return status;
- }
- msleep(ISL29018_CONV_TIME_MS);
- status = regmap_read(chip->regmap, ISL29018_REG_ADD_DATA_LSB, &lsb);
- if (status < 0) {
- dev_err(dev,
- "Error in reading LSB DATA with err %d\n", status);
- return status;
- }
-
- status = regmap_read(chip->regmap, ISL29018_REG_ADD_DATA_MSB, &msb);
- if (status < 0) {
- dev_err(dev,
- "Error in reading MSB DATA with error %d\n", status);
- return status;
- }
- dev_vdbg(dev, "MSB 0x%x and LSB 0x%x\n", msb, lsb);
-
- return (msb << 8) | lsb;
-}
-
-static int isl29018_read_lux(struct isl29018_chip *chip, int *lux)
-{
- int lux_data;
- unsigned int data_x_range;
-
- lux_data = isl29018_read_sensor_input(chip,
- ISL29018_CMD1_OPMODE_ALS_ONCE);
- if (lux_data < 0)
- return lux_data;
-
- data_x_range = lux_data * chip->scale.scale +
- lux_data * chip->scale.uscale / 1000000;
- *lux = data_x_range * chip->calibscale +
- data_x_range * chip->ucalibscale / 1000000;
-
- return 0;
-}
-
-static int isl29018_read_ir(struct isl29018_chip *chip, int *ir)
-{
- int ir_data;
-
- ir_data = isl29018_read_sensor_input(chip,
- ISL29018_CMD1_OPMODE_IR_ONCE);
- if (ir_data < 0)
- return ir_data;
-
- *ir = ir_data;
-
- return 0;
-}
-
-static int isl29018_read_proximity_ir(struct isl29018_chip *chip, int scheme,
- int *near_ir)
-{
- int status;
- int prox_data = -1;
- int ir_data = -1;
- struct device *dev = regmap_get_device(chip->regmap);
-
- /* Do proximity sensing with required scheme */
- status = regmap_update_bits(chip->regmap, ISL29018_REG_ADD_COMMAND2,
- ISL29018_CMD2_SCHEME_MASK,
- scheme << ISL29018_CMD2_SCHEME_SHIFT);
- if (status) {
- dev_err(dev, "Error in setting operating mode\n");
- return status;
- }
-
- prox_data = isl29018_read_sensor_input(chip,
- ISL29018_CMD1_OPMODE_PROX_ONCE);
- if (prox_data < 0)
- return prox_data;
-
- if (scheme == 1) {
- *near_ir = prox_data;
- return 0;
- }
-
- ir_data = isl29018_read_sensor_input(chip,
- ISL29018_CMD1_OPMODE_IR_ONCE);
- if (ir_data < 0)
- return ir_data;
-
- if (prox_data >= ir_data)
- *near_ir = prox_data - ir_data;
- else
- *near_ir = 0;
-
- return 0;
-}
-
-static ssize_t isl29018_show_scale_available(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct isl29018_chip *chip = iio_priv(indio_dev);
- int i, len = 0;
-
- for (i = 0; i < ARRAY_SIZE(isl29018_scales[chip->int_time]); ++i)
- len += sprintf(buf + len, "%d.%06d ",
- isl29018_scales[chip->int_time][i].scale,
- isl29018_scales[chip->int_time][i].uscale);
-
- buf[len - 1] = '\n';
-
- return len;
-}
-
-static ssize_t isl29018_show_int_time_available(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct isl29018_chip *chip = iio_priv(indio_dev);
- int i, len = 0;
-
- for (i = 0; i < ARRAY_SIZE(isl29018_int_utimes[chip->type]); ++i)
- len += sprintf(buf + len, "0.%06d ",
- isl29018_int_utimes[chip->type][i]);
-
- buf[len - 1] = '\n';
-
- return len;
-}
-
-static ssize_t isl29018_show_prox_infrared_suppression(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct isl29018_chip *chip = iio_priv(indio_dev);
-
- /*
- * Return the "proximity scheme" i.e. if the chip does on chip
- * infrared suppression (1 means perform on chip suppression)
- */
- return sprintf(buf, "%d\n", chip->prox_scheme);
-}
-
-static ssize_t isl29018_store_prox_infrared_suppression(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct isl29018_chip *chip = iio_priv(indio_dev);
- int val;
-
- if (kstrtoint(buf, 10, &val))
- return -EINVAL;
- if (!(val == 0 || val == 1))
- return -EINVAL;
-
- /*
- * Get the "proximity scheme" i.e. if the chip does on chip
- * infrared suppression (1 means perform on chip suppression)
- */
- mutex_lock(&chip->lock);
- chip->prox_scheme = val;
- mutex_unlock(&chip->lock);
-
- return count;
-}
-
-static int isl29018_write_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int val,
- int val2,
- long mask)
-{
- struct isl29018_chip *chip = iio_priv(indio_dev);
- int ret = -EINVAL;
-
- mutex_lock(&chip->lock);
- switch (mask) {
- case IIO_CHAN_INFO_CALIBSCALE:
- if (chan->type == IIO_LIGHT) {
- chip->calibscale = val;
- chip->ucalibscale = val2;
- ret = 0;
- }
- break;
- case IIO_CHAN_INFO_INT_TIME:
- if (chan->type == IIO_LIGHT) {
- if (val) {
- mutex_unlock(&chip->lock);
- return -EINVAL;
- }
- ret = isl29018_set_integration_time(chip, val2);
- }
- break;
- case IIO_CHAN_INFO_SCALE:
- if (chan->type == IIO_LIGHT)
- ret = isl29018_set_scale(chip, val, val2);
- break;
- default:
- break;
- }
- mutex_unlock(&chip->lock);
-
- return ret;
-}
-
-static int isl29018_read_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int *val,
- int *val2,
- long mask)
-{
- int ret = -EINVAL;
- struct isl29018_chip *chip = iio_priv(indio_dev);
-
- mutex_lock(&chip->lock);
- if (chip->suspended) {
- mutex_unlock(&chip->lock);
- return -EBUSY;
- }
- switch (mask) {
- case IIO_CHAN_INFO_RAW:
- case IIO_CHAN_INFO_PROCESSED:
- switch (chan->type) {
- case IIO_LIGHT:
- ret = isl29018_read_lux(chip, val);
- break;
- case IIO_INTENSITY:
- ret = isl29018_read_ir(chip, val);
- break;
- case IIO_PROXIMITY:
- ret = isl29018_read_proximity_ir(chip,
- chip->prox_scheme,
- val);
- break;
- default:
- break;
- }
- if (!ret)
- ret = IIO_VAL_INT;
- break;
- case IIO_CHAN_INFO_INT_TIME:
- if (chan->type == IIO_LIGHT) {
- *val = 0;
- *val2 = isl29018_int_utimes[chip->type][chip->int_time];
- ret = IIO_VAL_INT_PLUS_MICRO;
- }
- break;
- case IIO_CHAN_INFO_SCALE:
- if (chan->type == IIO_LIGHT) {
- *val = chip->scale.scale;
- *val2 = chip->scale.uscale;
- ret = IIO_VAL_INT_PLUS_MICRO;
- }
- break;
- case IIO_CHAN_INFO_CALIBSCALE:
- if (chan->type == IIO_LIGHT) {
- *val = chip->calibscale;
- *val2 = chip->ucalibscale;
- ret = IIO_VAL_INT_PLUS_MICRO;
- }
- break;
- default:
- break;
- }
- mutex_unlock(&chip->lock);
- return ret;
-}
-
-#define ISL29018_LIGHT_CHANNEL { \
- .type = IIO_LIGHT, \
- .indexed = 1, \
- .channel = 0, \
- .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | \
- BIT(IIO_CHAN_INFO_CALIBSCALE) | \
- BIT(IIO_CHAN_INFO_SCALE) | \
- BIT(IIO_CHAN_INFO_INT_TIME), \
-}
-
-#define ISL29018_IR_CHANNEL { \
- .type = IIO_INTENSITY, \
- .modified = 1, \
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
- .channel2 = IIO_MOD_LIGHT_IR, \
-}
-
-#define ISL29018_PROXIMITY_CHANNEL { \
- .type = IIO_PROXIMITY, \
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
-}
-
-static const struct iio_chan_spec isl29018_channels[] = {
- ISL29018_LIGHT_CHANNEL,
- ISL29018_IR_CHANNEL,
- ISL29018_PROXIMITY_CHANNEL,
-};
-
-static const struct iio_chan_spec isl29023_channels[] = {
- ISL29018_LIGHT_CHANNEL,
- ISL29018_IR_CHANNEL,
-};
-
-static IIO_DEVICE_ATTR(in_illuminance_integration_time_available, S_IRUGO,
- isl29018_show_int_time_available, NULL, 0);
-static IIO_DEVICE_ATTR(in_illuminance_scale_available, S_IRUGO,
- isl29018_show_scale_available, NULL, 0);
-static IIO_DEVICE_ATTR(proximity_on_chip_ambient_infrared_suppression,
- S_IRUGO | S_IWUSR,
- isl29018_show_prox_infrared_suppression,
- isl29018_store_prox_infrared_suppression, 0);
-
-#define ISL29018_DEV_ATTR(name) (&iio_dev_attr_##name.dev_attr.attr)
-
-static struct attribute *isl29018_attributes[] = {
- ISL29018_DEV_ATTR(in_illuminance_scale_available),
- ISL29018_DEV_ATTR(in_illuminance_integration_time_available),
- ISL29018_DEV_ATTR(proximity_on_chip_ambient_infrared_suppression),
- NULL
-};
-
-static struct attribute *isl29023_attributes[] = {
- ISL29018_DEV_ATTR(in_illuminance_scale_available),
- ISL29018_DEV_ATTR(in_illuminance_integration_time_available),
- NULL
-};
-
-static const struct attribute_group isl29018_group = {
- .attrs = isl29018_attributes,
-};
-
-static const struct attribute_group isl29023_group = {
- .attrs = isl29023_attributes,
-};
-
-static int isl29035_detect(struct isl29018_chip *chip)
-{
- int status;
- unsigned int id;
- struct device *dev = regmap_get_device(chip->regmap);
-
- status = regmap_read(chip->regmap, ISL29035_REG_DEVICE_ID, &id);
- if (status < 0) {
- dev_err(dev,
- "Error reading ID register with error %d\n",
- status);
- return status;
- }
-
- id = (id & ISL29035_DEVICE_ID_MASK) >> ISL29035_DEVICE_ID_SHIFT;
-
- if (id != ISL29035_DEVICE_ID)
- return -ENODEV;
-
- /* Clear brownout bit */
- return regmap_update_bits(chip->regmap, ISL29035_REG_DEVICE_ID,
- ISL29035_BOUT_MASK, 0);
-}
-
-enum {
- isl29018,
- isl29023,
- isl29035,
-};
-
-static int isl29018_chip_init(struct isl29018_chip *chip)
-{
- int status;
- struct device *dev = regmap_get_device(chip->regmap);
-
- if (chip->type == isl29035) {
- status = isl29035_detect(chip);
- if (status < 0)
- return status;
- }
-
- /* Code added per Intersil Application Note 1534:
- * When VDD sinks to approximately 1.8V or below, some of
- * the part's registers may change their state. When VDD
- * recovers to 2.25V (or greater), the part may thus be in an
- * unknown mode of operation. The user can return the part to
- * a known mode of operation either by (a) setting VDD = 0V for
- * 1 second or more and then powering back up with a slew rate
- * of 0.5V/ms or greater, or (b) via I2C disable all ALS/PROX
- * conversions, clear the test registers, and then rewrite all
- * registers to the desired values.
- * ...
- * For ISL29011, ISL29018, ISL29021, ISL29023
- * 1. Write 0x00 to register 0x08 (TEST)
- * 2. Write 0x00 to register 0x00 (CMD1)
- * 3. Rewrite all registers to the desired values
- *
- * ISL29018 Data Sheet (FN6619.1, Feb 11, 2010) essentially says
- * the same thing EXCEPT the data sheet asks for a 1ms delay after
- * writing the CMD1 register.
- */
- status = regmap_write(chip->regmap, ISL29018_REG_TEST, 0x0);
- if (status < 0) {
- dev_err(dev, "Failed to clear isl29018 TEST reg.(%d)\n",
- status);
- return status;
- }
-
- /* See Intersil AN1534 comments above.
- * "Operating Mode" (COMMAND1) register is reprogrammed when
- * data is read from the device.
- */
- status = regmap_write(chip->regmap, ISL29018_REG_ADD_COMMAND1, 0);
- if (status < 0) {
- dev_err(dev, "Failed to clear isl29018 CMD1 reg.(%d)\n",
- status);
- return status;
- }
-
- usleep_range(1000, 2000); /* per data sheet, page 10 */
-
- /* Set defaults */
- status = isl29018_set_scale(chip, chip->scale.scale,
- chip->scale.uscale);
- if (status < 0) {
- dev_err(dev, "Init of isl29018 fails\n");
- return status;
- }
-
- status = isl29018_set_integration_time(chip,
- isl29018_int_utimes[chip->type][chip->int_time]);
- if (status < 0) {
- dev_err(dev, "Init of isl29018 fails\n");
- return status;
- }
-
- return 0;
-}
-
-static const struct iio_info isl29018_info = {
- .attrs = &isl29018_group,
- .driver_module = THIS_MODULE,
- .read_raw = isl29018_read_raw,
- .write_raw = isl29018_write_raw,
-};
-
-static const struct iio_info isl29023_info = {
- .attrs = &isl29023_group,
- .driver_module = THIS_MODULE,
- .read_raw = isl29018_read_raw,
- .write_raw = isl29018_write_raw,
-};
-
-static bool isl29018_is_volatile_reg(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case ISL29018_REG_ADD_DATA_LSB:
- case ISL29018_REG_ADD_DATA_MSB:
- case ISL29018_REG_ADD_COMMAND1:
- case ISL29018_REG_TEST:
- case ISL29035_REG_DEVICE_ID:
- return true;
- default:
- return false;
- }
-}
-
-static const struct regmap_config isl29018_regmap_config = {
- .reg_bits = 8,
- .val_bits = 8,
- .volatile_reg = isl29018_is_volatile_reg,
- .max_register = ISL29018_REG_TEST,
- .num_reg_defaults_raw = ISL29018_REG_TEST + 1,
- .cache_type = REGCACHE_RBTREE,
-};
-
-static const struct regmap_config isl29035_regmap_config = {
- .reg_bits = 8,
- .val_bits = 8,
- .volatile_reg = isl29018_is_volatile_reg,
- .max_register = ISL29035_REG_DEVICE_ID,
- .num_reg_defaults_raw = ISL29035_REG_DEVICE_ID + 1,
- .cache_type = REGCACHE_RBTREE,
-};
-
-struct isl29018_chip_info {
- const struct iio_chan_spec *channels;
- int num_channels;
- const struct iio_info *indio_info;
- const struct regmap_config *regmap_cfg;
-};
-
-static const struct isl29018_chip_info isl29018_chip_info_tbl[] = {
- [isl29018] = {
- .channels = isl29018_channels,
- .num_channels = ARRAY_SIZE(isl29018_channels),
- .indio_info = &isl29018_info,
- .regmap_cfg = &isl29018_regmap_config,
- },
- [isl29023] = {
- .channels = isl29023_channels,
- .num_channels = ARRAY_SIZE(isl29023_channels),
- .indio_info = &isl29023_info,
- .regmap_cfg = &isl29018_regmap_config,
- },
- [isl29035] = {
- .channels = isl29023_channels,
- .num_channels = ARRAY_SIZE(isl29023_channels),
- .indio_info = &isl29023_info,
- .regmap_cfg = &isl29035_regmap_config,
- },
-};
-
-static const char *isl29018_match_acpi_device(struct device *dev, int *data)
-{
- const struct acpi_device_id *id;
-
- id = acpi_match_device(dev->driver->acpi_match_table, dev);
-
- if (!id)
- return NULL;
-
- *data = (int)id->driver_data;
-
- return dev_name(dev);
-}
-
-static int isl29018_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct isl29018_chip *chip;
- struct iio_dev *indio_dev;
- int err;
- const char *name = NULL;
- int dev_id = 0;
-
- indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
- if (!indio_dev)
- return -ENOMEM;
- chip = iio_priv(indio_dev);
-
- i2c_set_clientdata(client, indio_dev);
-
- if (id) {
- name = id->name;
- dev_id = id->driver_data;
- }
-
- if (ACPI_HANDLE(&client->dev))
- name = isl29018_match_acpi_device(&client->dev, &dev_id);
-
- mutex_init(&chip->lock);
-
- chip->type = dev_id;
- chip->calibscale = 1;
- chip->ucalibscale = 0;
- chip->int_time = ISL29018_INT_TIME_16;
- chip->scale = isl29018_scales[chip->int_time][0];
- chip->suspended = false;
-
- chip->regmap = devm_regmap_init_i2c(client,
- isl29018_chip_info_tbl[dev_id].regmap_cfg);
- if (IS_ERR(chip->regmap)) {
- err = PTR_ERR(chip->regmap);
- dev_err(&client->dev, "regmap initialization fails: %d\n", err);
- return err;
- }
-
- err = isl29018_chip_init(chip);
- if (err)
- return err;
-
- indio_dev->info = isl29018_chip_info_tbl[dev_id].indio_info;
- indio_dev->channels = isl29018_chip_info_tbl[dev_id].channels;
- indio_dev->num_channels = isl29018_chip_info_tbl[dev_id].num_channels;
- indio_dev->name = name;
- indio_dev->dev.parent = &client->dev;
- indio_dev->modes = INDIO_DIRECT_MODE;
- return devm_iio_device_register(&client->dev, indio_dev);
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int isl29018_suspend(struct device *dev)
-{
- struct isl29018_chip *chip = iio_priv(dev_get_drvdata(dev));
-
- mutex_lock(&chip->lock);
-
- /* Since this driver uses only polling commands, we are by default in
- * auto shutdown (ie, power-down) mode.
- * So we do not have much to do here.
- */
- chip->suspended = true;
-
- mutex_unlock(&chip->lock);
- return 0;
-}
-
-static int isl29018_resume(struct device *dev)
-{
- struct isl29018_chip *chip = iio_priv(dev_get_drvdata(dev));
- int err;
-
- mutex_lock(&chip->lock);
-
- err = isl29018_chip_init(chip);
- if (!err)
- chip->suspended = false;
-
- mutex_unlock(&chip->lock);
- return err;
-}
-
-static SIMPLE_DEV_PM_OPS(isl29018_pm_ops, isl29018_suspend, isl29018_resume);
-#define ISL29018_PM_OPS (&isl29018_pm_ops)
-#else
-#define ISL29018_PM_OPS NULL
-#endif
-
-static const struct acpi_device_id isl29018_acpi_match[] = {
- {"ISL29018", isl29018},
- {"ISL29023", isl29023},
- {"ISL29035", isl29035},
- {},
-};
-MODULE_DEVICE_TABLE(acpi, isl29018_acpi_match);
-
-static const struct i2c_device_id isl29018_id[] = {
- {"isl29018", isl29018},
- {"isl29023", isl29023},
- {"isl29035", isl29035},
- {}
-};
-
-MODULE_DEVICE_TABLE(i2c, isl29018_id);
-
-static const struct of_device_id isl29018_of_match[] = {
- { .compatible = "isil,isl29018", },
- { .compatible = "isil,isl29023", },
- { .compatible = "isil,isl29035", },
- { },
-};
-MODULE_DEVICE_TABLE(of, isl29018_of_match);
-
-static struct i2c_driver isl29018_driver = {
- .driver = {
- .name = "isl29018",
- .acpi_match_table = ACPI_PTR(isl29018_acpi_match),
- .pm = ISL29018_PM_OPS,
- .of_match_table = isl29018_of_match,
- },
- .probe = isl29018_probe,
- .id_table = isl29018_id,
-};
-module_i2c_driver(isl29018_driver);
-
-MODULE_DESCRIPTION("ISL29018 Ambient Light Sensor driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/iio/light/tsl2583.c b/drivers/staging/iio/light/tsl2583.c
deleted file mode 100644
index 08f1583ee34e..000000000000
--- a/drivers/staging/iio/light/tsl2583.c
+++ /dev/null
@@ -1,963 +0,0 @@
-/*
- * Device driver for monitoring ambient light intensity (lux)
- * within the TAOS tsl258x family of devices (tsl2580, tsl2581).
- *
- * Copyright (c) 2011, TAOS Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/i2c.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/mutex.h>
-#include <linux/unistd.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/iio/iio.h>
-
-#define TSL258X_MAX_DEVICE_REGS 32
-
-/* Triton register offsets */
-#define TSL258X_REG_MAX 8
-
-/* Device Registers and Masks */
-#define TSL258X_CNTRL 0x00
-#define TSL258X_ALS_TIME 0X01
-#define TSL258X_INTERRUPT 0x02
-#define TSL258X_GAIN 0x07
-#define TSL258X_REVID 0x11
-#define TSL258X_CHIPID 0x12
-#define TSL258X_ALS_CHAN0LO 0x14
-#define TSL258X_ALS_CHAN0HI 0x15
-#define TSL258X_ALS_CHAN1LO 0x16
-#define TSL258X_ALS_CHAN1HI 0x17
-#define TSL258X_TMR_LO 0x18
-#define TSL258X_TMR_HI 0x19
-
-/* tsl2583 cmd reg masks */
-#define TSL258X_CMD_REG 0x80
-#define TSL258X_CMD_SPL_FN 0x60
-#define TSL258X_CMD_ALS_INT_CLR 0X01
-
-/* tsl2583 cntrl reg masks */
-#define TSL258X_CNTL_ADC_ENBL 0x02
-#define TSL258X_CNTL_PWR_ON 0x01
-
-/* tsl2583 status reg masks */
-#define TSL258X_STA_ADC_VALID 0x01
-#define TSL258X_STA_ADC_INTR 0x10
-
-/* Lux calculation constants */
-#define TSL258X_LUX_CALC_OVER_FLOW 65535
-
-enum {
- TSL258X_CHIP_UNKNOWN = 0,
- TSL258X_CHIP_WORKING = 1,
- TSL258X_CHIP_SUSPENDED = 2
-};
-
-/* Per-device data */
-struct taos_als_info {
- u16 als_ch0;
- u16 als_ch1;
- u16 lux;
-};
-
-struct taos_settings {
- int als_time;
- int als_gain;
- int als_gain_trim;
- int als_cal_target;
-};
-
-struct tsl2583_chip {
- struct mutex als_mutex;
- struct i2c_client *client;
- struct taos_als_info als_cur_info;
- struct taos_settings taos_settings;
- int als_time_scale;
- int als_saturation;
- int taos_chip_status;
- u8 taos_config[8];
-};
-
-/*
- * Initial values for device - this values can/will be changed by driver.
- * and applications as needed.
- * These values are dynamic.
- */
-static const u8 taos_config[8] = {
- 0x00, 0xee, 0x00, 0x03, 0x00, 0xFF, 0xFF, 0x00
-}; /* cntrl atime intC Athl0 Athl1 Athh0 Athh1 gain */
-
-struct taos_lux {
- unsigned int ratio;
- unsigned int ch0;
- unsigned int ch1;
-};
-
-/* This structure is intentionally large to accommodate updates via sysfs. */
-/* Sized to 11 = max 10 segments + 1 termination segment */
-/* Assumption is one and only one type of glass used */
-static struct taos_lux taos_device_lux[11] = {
- { 9830, 8520, 15729 },
- { 12452, 10807, 23344 },
- { 14746, 6383, 11705 },
- { 17695, 4063, 6554 },
-};
-
-struct gainadj {
- s16 ch0;
- s16 ch1;
-};
-
-/* Index = (0 - 3) Used to validate the gain selection index */
-static const struct gainadj gainadj[] = {
- { 1, 1 },
- { 8, 8 },
- { 16, 16 },
- { 107, 115 }
-};
-
-/*
- * Provides initial operational parameter defaults.
- * These defaults may be changed through the device's sysfs files.
- */
-static void taos_defaults(struct tsl2583_chip *chip)
-{
- /* Operational parameters */
- chip->taos_settings.als_time = 100;
- /* must be a multiple of 50mS */
- chip->taos_settings.als_gain = 0;
- /* this is actually an index into the gain table */
- /* assume clear glass as default */
- chip->taos_settings.als_gain_trim = 1000;
- /* default gain trim to account for aperture effects */
- chip->taos_settings.als_cal_target = 130;
- /* Known external ALS reading used for calibration */
-}
-
-/*
- * Read a number of bytes starting at register (reg) location.
- * Return 0, or i2c_smbus_write_byte ERROR code.
- */
-static int
-taos_i2c_read(struct i2c_client *client, u8 reg, u8 *val, unsigned int len)
-{
- int i, ret;
-
- for (i = 0; i < len; i++) {
- /* select register to write */
- ret = i2c_smbus_write_byte(client, (TSL258X_CMD_REG | reg));
- if (ret < 0) {
- dev_err(&client->dev,
- "taos_i2c_read failed to write register %x\n",
- reg);
- return ret;
- }
- /* read the data */
- *val = i2c_smbus_read_byte(client);
- val++;
- reg++;
- }
- return 0;
-}
-
-/*
- * Reads and calculates current lux value.
- * The raw ch0 and ch1 values of the ambient light sensed in the last
- * integration cycle are read from the device.
- * Time scale factor array values are adjusted based on the integration time.
- * The raw values are multiplied by a scale factor, and device gain is obtained
- * using gain index. Limit checks are done next, then the ratio of a multiple
- * of ch1 value, to the ch0 value, is calculated. The array taos_device_lux[]
- * declared above is then scanned to find the first ratio value that is just
- * above the ratio we just calculated. The ch0 and ch1 multiplier constants in
- * the array are then used along with the time scale factor array values, to
- * calculate the lux.
- */
-static int taos_get_lux(struct iio_dev *indio_dev)
-{
- u16 ch0, ch1; /* separated ch0/ch1 data from device */
- u32 lux; /* raw lux calculated from device data */
- u64 lux64;
- u32 ratio;
- u8 buf[5];
- struct taos_lux *p;
- struct tsl2583_chip *chip = iio_priv(indio_dev);
- int i, ret;
- u32 ch0lux = 0;
- u32 ch1lux = 0;
-
- if (mutex_trylock(&chip->als_mutex) == 0) {
- dev_info(&chip->client->dev, "taos_get_lux device is busy\n");
- return chip->als_cur_info.lux; /* busy, so return LAST VALUE */
- }
-
- if (chip->taos_chip_status != TSL258X_CHIP_WORKING) {
- /* device is not enabled */
- dev_err(&chip->client->dev, "taos_get_lux device is not enabled\n");
- ret = -EBUSY;
- goto out_unlock;
- }
-
- ret = taos_i2c_read(chip->client, (TSL258X_CMD_REG), &buf[0], 1);
- if (ret < 0) {
- dev_err(&chip->client->dev, "taos_get_lux failed to read CMD_REG\n");
- goto out_unlock;
- }
- /* is data new & valid */
- if (!(buf[0] & TSL258X_STA_ADC_INTR)) {
- dev_err(&chip->client->dev, "taos_get_lux data not valid\n");
- ret = chip->als_cur_info.lux; /* return LAST VALUE */
- goto out_unlock;
- }
-
- for (i = 0; i < 4; i++) {
- int reg = TSL258X_CMD_REG | (TSL258X_ALS_CHAN0LO + i);
-
- ret = taos_i2c_read(chip->client, reg, &buf[i], 1);
- if (ret < 0) {
- dev_err(&chip->client->dev,
- "taos_get_lux failed to read register %x\n",
- reg);
- goto out_unlock;
- }
- }
-
- /*
- * clear status, really interrupt status (interrupts are off), but
- * we use the bit anyway - don't forget 0x80 - this is a command
- */
- ret = i2c_smbus_write_byte(chip->client,
- (TSL258X_CMD_REG | TSL258X_CMD_SPL_FN |
- TSL258X_CMD_ALS_INT_CLR));
-
- if (ret < 0) {
- dev_err(&chip->client->dev,
- "taos_i2c_write_command failed in taos_get_lux, err = %d\n",
- ret);
- goto out_unlock; /* have no data, so return failure */
- }
-
- /* extract ALS/lux data */
- ch0 = le16_to_cpup((const __le16 *)&buf[0]);
- ch1 = le16_to_cpup((const __le16 *)&buf[2]);
-
- chip->als_cur_info.als_ch0 = ch0;
- chip->als_cur_info.als_ch1 = ch1;
-
- if ((ch0 >= chip->als_saturation) || (ch1 >= chip->als_saturation))
- goto return_max;
-
- if (!ch0) {
- /* have no data, so return LAST VALUE */
- ret = 0;
- chip->als_cur_info.lux = 0;
- goto out_unlock;
- }
- /* calculate ratio */
- ratio = (ch1 << 15) / ch0;
- /* convert to unscaled lux using the pointer to the table */
- for (p = (struct taos_lux *)taos_device_lux;
- p->ratio != 0 && p->ratio < ratio; p++)
- ;
-
- if (p->ratio == 0) {
- lux = 0;
- } else {
- ch0lux = ((ch0 * p->ch0) +
- (gainadj[chip->taos_settings.als_gain].ch0 >> 1))
- / gainadj[chip->taos_settings.als_gain].ch0;
- ch1lux = ((ch1 * p->ch1) +
- (gainadj[chip->taos_settings.als_gain].ch1 >> 1))
- / gainadj[chip->taos_settings.als_gain].ch1;
- lux = ch0lux - ch1lux;
- }
-
- /* note: lux is 31 bit max at this point */
- if (ch1lux > ch0lux) {
- dev_dbg(&chip->client->dev, "No Data - Return last value\n");
- ret = 0;
- chip->als_cur_info.lux = 0;
- goto out_unlock;
- }
-
- /* adjust for active time scale */
- if (chip->als_time_scale == 0)
- lux = 0;
- else
- lux = (lux + (chip->als_time_scale >> 1)) /
- chip->als_time_scale;
-
- /* Adjust for active gain scale.
- * The taos_device_lux tables above have a factor of 8192 built in,
- * so we need to shift right.
- * User-specified gain provides a multiplier.
- * Apply user-specified gain before shifting right to retain precision.
- * Use 64 bits to avoid overflow on multiplication.
- * Then go back to 32 bits before division to avoid using div_u64().
- */
- lux64 = lux;
- lux64 = lux64 * chip->taos_settings.als_gain_trim;
- lux64 >>= 13;
- lux = lux64;
- lux = (lux + 500) / 1000;
- if (lux > TSL258X_LUX_CALC_OVER_FLOW) { /* check for overflow */
-return_max:
- lux = TSL258X_LUX_CALC_OVER_FLOW;
- }
-
- /* Update the structure with the latest VALID lux. */
- chip->als_cur_info.lux = lux;
- ret = lux;
-
-out_unlock:
- mutex_unlock(&chip->als_mutex);
- return ret;
-}
-
-/*
- * Obtain single reading and calculate the als_gain_trim (later used
- * to derive actual lux).
- * Return updated gain_trim value.
- */
-static int taos_als_calibrate(struct iio_dev *indio_dev)
-{
- struct tsl2583_chip *chip = iio_priv(indio_dev);
- u8 reg_val;
- unsigned int gain_trim_val;
- int ret;
- int lux_val;
-
- ret = i2c_smbus_write_byte(chip->client,
- (TSL258X_CMD_REG | TSL258X_CNTRL));
- if (ret < 0) {
- dev_err(&chip->client->dev,
- "taos_als_calibrate failed to reach the CNTRL register, ret=%d\n",
- ret);
- return ret;
- }
-
- reg_val = i2c_smbus_read_byte(chip->client);
- if ((reg_val & (TSL258X_CNTL_ADC_ENBL | TSL258X_CNTL_PWR_ON))
- != (TSL258X_CNTL_ADC_ENBL | TSL258X_CNTL_PWR_ON)) {
- dev_err(&chip->client->dev,
- "taos_als_calibrate failed: device not powered on with ADC enabled\n");
- return -1;
- }
-
- ret = i2c_smbus_write_byte(chip->client,
- (TSL258X_CMD_REG | TSL258X_CNTRL));
- if (ret < 0) {
- dev_err(&chip->client->dev,
- "taos_als_calibrate failed to reach the STATUS register, ret=%d\n",
- ret);
- return ret;
- }
- reg_val = i2c_smbus_read_byte(chip->client);
-
- if ((reg_val & TSL258X_STA_ADC_VALID) != TSL258X_STA_ADC_VALID) {
- dev_err(&chip->client->dev,
- "taos_als_calibrate failed: STATUS - ADC not valid.\n");
- return -ENODATA;
- }
- lux_val = taos_get_lux(indio_dev);
- if (lux_val < 0) {
- dev_err(&chip->client->dev, "taos_als_calibrate failed to get lux\n");
- return lux_val;
- }
- gain_trim_val = (unsigned int)(((chip->taos_settings.als_cal_target)
- * chip->taos_settings.als_gain_trim) / lux_val);
-
- if ((gain_trim_val < 250) || (gain_trim_val > 4000)) {
- dev_err(&chip->client->dev,
- "taos_als_calibrate failed: trim_val of %d is out of range\n",
- gain_trim_val);
- return -ENODATA;
- }
- chip->taos_settings.als_gain_trim = (int)gain_trim_val;
-
- return (int)gain_trim_val;
-}
-
-/*
- * Turn the device on.
- * Configuration must be set before calling this function.
- */
-static int taos_chip_on(struct iio_dev *indio_dev)
-{
- int i;
- int ret;
- u8 *uP;
- u8 utmp;
- int als_count;
- int als_time;
- struct tsl2583_chip *chip = iio_priv(indio_dev);
-
- /* and make sure we're not already on */
- if (chip->taos_chip_status == TSL258X_CHIP_WORKING) {
- /* if forcing a register update - turn off, then on */
- dev_info(&chip->client->dev, "device is already enabled\n");
- return -EINVAL;
- }
-
- /* determine als integration register */
- als_count = (chip->taos_settings.als_time * 100 + 135) / 270;
- if (!als_count)
- als_count = 1; /* ensure at least one cycle */
-
- /* convert back to time (encompasses overrides) */
- als_time = (als_count * 27 + 5) / 10;
- chip->taos_config[TSL258X_ALS_TIME] = 256 - als_count;
-
- /* Set the gain based on taos_settings struct */
- chip->taos_config[TSL258X_GAIN] = chip->taos_settings.als_gain;
-
- /* set chip struct re scaling and saturation */
- chip->als_saturation = als_count * 922; /* 90% of full scale */
- chip->als_time_scale = (als_time + 25) / 50;
-
- /*
- * TSL258x Specific power-on / adc enable sequence
- * Power on the device 1st.
- */
- utmp = TSL258X_CNTL_PWR_ON;
- ret = i2c_smbus_write_byte_data(chip->client,
- TSL258X_CMD_REG | TSL258X_CNTRL, utmp);
- if (ret < 0) {
- dev_err(&chip->client->dev, "taos_chip_on failed on CNTRL reg.\n");
- return ret;
- }
-
- /*
- * Use the following shadow copy for our delay before enabling ADC.
- * Write all the registers.
- */
- for (i = 0, uP = chip->taos_config; i < TSL258X_REG_MAX; i++) {
- ret = i2c_smbus_write_byte_data(chip->client,
- TSL258X_CMD_REG + i,
- *uP++);
- if (ret < 0) {
- dev_err(&chip->client->dev,
- "taos_chip_on failed on reg %d.\n", i);
- return ret;
- }
- }
-
- usleep_range(3000, 3500);
- /*
- * NOW enable the ADC
- * initialize the desired mode of operation
- */
- utmp = TSL258X_CNTL_PWR_ON | TSL258X_CNTL_ADC_ENBL;
- ret = i2c_smbus_write_byte_data(chip->client,
- TSL258X_CMD_REG | TSL258X_CNTRL,
- utmp);
- if (ret < 0) {
- dev_err(&chip->client->dev, "taos_chip_on failed on 2nd CTRL reg.\n");
- return ret;
- }
- chip->taos_chip_status = TSL258X_CHIP_WORKING;
-
- return ret;
-}
-
-static int taos_chip_off(struct iio_dev *indio_dev)
-{
- struct tsl2583_chip *chip = iio_priv(indio_dev);
-
- /* turn device off */
- chip->taos_chip_status = TSL258X_CHIP_SUSPENDED;
- return i2c_smbus_write_byte_data(chip->client,
- TSL258X_CMD_REG | TSL258X_CNTRL,
- 0x00);
-}
-
-/* Sysfs Interface Functions */
-
-static ssize_t taos_power_state_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct tsl2583_chip *chip = iio_priv(indio_dev);
-
- return sprintf(buf, "%d\n", chip->taos_chip_status);
-}
-
-static ssize_t taos_power_state_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- int value;
-
- if (kstrtoint(buf, 0, &value))
- return -EINVAL;
-
- if (!value)
- taos_chip_off(indio_dev);
- else
- taos_chip_on(indio_dev);
-
- return len;
-}
-
-static ssize_t taos_gain_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct tsl2583_chip *chip = iio_priv(indio_dev);
- char gain[4] = {0};
-
- switch (chip->taos_settings.als_gain) {
- case 0:
- strcpy(gain, "001");
- break;
- case 1:
- strcpy(gain, "008");
- break;
- case 2:
- strcpy(gain, "016");
- break;
- case 3:
- strcpy(gain, "111");
- break;
- }
-
- return sprintf(buf, "%s\n", gain);
-}
-
-static ssize_t taos_gain_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct tsl2583_chip *chip = iio_priv(indio_dev);
- int value;
-
- if (kstrtoint(buf, 0, &value))
- return -EINVAL;
-
- switch (value) {
- case 1:
- chip->taos_settings.als_gain = 0;
- break;
- case 8:
- chip->taos_settings.als_gain = 1;
- break;
- case 16:
- chip->taos_settings.als_gain = 2;
- break;
- case 111:
- chip->taos_settings.als_gain = 3;
- break;
- default:
- dev_err(dev, "Invalid Gain Index (must be 1,8,16,111)\n");
- return -1;
- }
-
- return len;
-}
-
-static ssize_t taos_gain_available_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- return sprintf(buf, "%s\n", "1 8 16 111");
-}
-
-static ssize_t taos_als_time_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct tsl2583_chip *chip = iio_priv(indio_dev);
-
- return sprintf(buf, "%d\n", chip->taos_settings.als_time);
-}
-
-static ssize_t taos_als_time_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct tsl2583_chip *chip = iio_priv(indio_dev);
- int value;
-
- if (kstrtoint(buf, 0, &value))
- return -EINVAL;
-
- if ((value < 50) || (value > 650))
- return -EINVAL;
-
- if (value % 50)
- return -EINVAL;
-
- chip->taos_settings.als_time = value;
-
- return len;
-}
-
-static ssize_t taos_als_time_available_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- return sprintf(buf, "%s\n",
- "50 100 150 200 250 300 350 400 450 500 550 600 650");
-}
-
-static ssize_t taos_als_trim_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct tsl2583_chip *chip = iio_priv(indio_dev);
-
- return sprintf(buf, "%d\n", chip->taos_settings.als_gain_trim);
-}
-
-static ssize_t taos_als_trim_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct tsl2583_chip *chip = iio_priv(indio_dev);
- int value;
-
- if (kstrtoint(buf, 0, &value))
- return -EINVAL;
-
- if (value)
- chip->taos_settings.als_gain_trim = value;
-
- return len;
-}
-
-static ssize_t taos_als_cal_target_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct tsl2583_chip *chip = iio_priv(indio_dev);
-
- return sprintf(buf, "%d\n", chip->taos_settings.als_cal_target);
-}
-
-static ssize_t taos_als_cal_target_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct tsl2583_chip *chip = iio_priv(indio_dev);
- int value;
-
- if (kstrtoint(buf, 0, &value))
- return -EINVAL;
-
- if (value)
- chip->taos_settings.als_cal_target = value;
-
- return len;
-}
-
-static ssize_t taos_lux_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- int ret;
-
- ret = taos_get_lux(dev_to_iio_dev(dev));
- if (ret < 0)
- return ret;
-
- return sprintf(buf, "%d\n", ret);
-}
-
-static ssize_t taos_do_calibrate(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- int value;
-
- if (kstrtoint(buf, 0, &value))
- return -EINVAL;
-
- if (value == 1)
- taos_als_calibrate(indio_dev);
-
- return len;
-}
-
-static ssize_t taos_luxtable_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- int i;
- int offset = 0;
-
- for (i = 0; i < ARRAY_SIZE(taos_device_lux); i++) {
- offset += sprintf(buf + offset, "%u,%u,%u,",
- taos_device_lux[i].ratio,
- taos_device_lux[i].ch0,
- taos_device_lux[i].ch1);
- if (taos_device_lux[i].ratio == 0) {
- /*
- * We just printed the first "0" entry.
- * Now get rid of the extra "," and break.
- */
- offset--;
- break;
- }
- }
-
- offset += sprintf(buf + offset, "\n");
- return offset;
-}
-
-static ssize_t taos_luxtable_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct tsl2583_chip *chip = iio_priv(indio_dev);
- int value[ARRAY_SIZE(taos_device_lux) * 3 + 1];
- int n;
-
- get_options(buf, ARRAY_SIZE(value), value);
-
- /* We now have an array of ints starting at value[1], and
- * enumerated by value[0].
- * We expect each group of three ints is one table entry,
- * and the last table entry is all 0.
- */
- n = value[0];
- if ((n % 3) || n < 6 || n > ((ARRAY_SIZE(taos_device_lux) - 1) * 3)) {
- dev_info(dev, "LUX TABLE INPUT ERROR 1 Value[0]=%d\n", n);
- return -EINVAL;
- }
- if ((value[(n - 2)] | value[(n - 1)] | value[n]) != 0) {
- dev_info(dev, "LUX TABLE INPUT ERROR 2 Value[0]=%d\n", n);
- return -EINVAL;
- }
-
- if (chip->taos_chip_status == TSL258X_CHIP_WORKING)
- taos_chip_off(indio_dev);
-
- /* Zero out the table */
- memset(taos_device_lux, 0, sizeof(taos_device_lux));
- memcpy(taos_device_lux, &value[1], (value[0] * 4));
-
- taos_chip_on(indio_dev);
-
- return len;
-}
-
-static DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR,
- taos_power_state_show, taos_power_state_store);
-
-static DEVICE_ATTR(illuminance0_calibscale, S_IRUGO | S_IWUSR,
- taos_gain_show, taos_gain_store);
-static DEVICE_ATTR(illuminance0_calibscale_available, S_IRUGO,
- taos_gain_available_show, NULL);
-
-static DEVICE_ATTR(illuminance0_integration_time, S_IRUGO | S_IWUSR,
- taos_als_time_show, taos_als_time_store);
-static DEVICE_ATTR(illuminance0_integration_time_available, S_IRUGO,
- taos_als_time_available_show, NULL);
-
-static DEVICE_ATTR(illuminance0_calibbias, S_IRUGO | S_IWUSR,
- taos_als_trim_show, taos_als_trim_store);
-
-static DEVICE_ATTR(illuminance0_input_target, S_IRUGO | S_IWUSR,
- taos_als_cal_target_show, taos_als_cal_target_store);
-
-static DEVICE_ATTR(illuminance0_input, S_IRUGO, taos_lux_show, NULL);
-static DEVICE_ATTR(illuminance0_calibrate, S_IWUSR, NULL, taos_do_calibrate);
-static DEVICE_ATTR(illuminance0_lux_table, S_IRUGO | S_IWUSR,
- taos_luxtable_show, taos_luxtable_store);
-
-static struct attribute *sysfs_attrs_ctrl[] = {
- &dev_attr_power_state.attr,
- &dev_attr_illuminance0_calibscale.attr, /* Gain */
- &dev_attr_illuminance0_calibscale_available.attr,
- &dev_attr_illuminance0_integration_time.attr, /* I time*/
- &dev_attr_illuminance0_integration_time_available.attr,
- &dev_attr_illuminance0_calibbias.attr, /* trim */
- &dev_attr_illuminance0_input_target.attr,
- &dev_attr_illuminance0_input.attr,
- &dev_attr_illuminance0_calibrate.attr,
- &dev_attr_illuminance0_lux_table.attr,
- NULL
-};
-
-static const struct attribute_group tsl2583_attribute_group = {
- .attrs = sysfs_attrs_ctrl,
-};
-
-/* Use the default register values to identify the Taos device */
-static int taos_tsl258x_device(unsigned char *bufp)
-{
- return ((bufp[TSL258X_CHIPID] & 0xf0) == 0x90);
-}
-
-static const struct iio_info tsl2583_info = {
- .attrs = &tsl2583_attribute_group,
- .driver_module = THIS_MODULE,
-};
-
-/*
- * Client probe function - When a valid device is found, the driver's device
- * data structure is updated, and initialization completes successfully.
- */
-static int taos_probe(struct i2c_client *clientp,
- const struct i2c_device_id *idp)
-{
- int i, ret;
- unsigned char buf[TSL258X_MAX_DEVICE_REGS];
- struct tsl2583_chip *chip;
- struct iio_dev *indio_dev;
-
- if (!i2c_check_functionality(clientp->adapter,
- I2C_FUNC_SMBUS_BYTE_DATA)) {
- dev_err(&clientp->dev, "taos_probe() - i2c smbus byte data func unsupported\n");
- return -EOPNOTSUPP;
- }
-
- indio_dev = devm_iio_device_alloc(&clientp->dev, sizeof(*chip));
- if (!indio_dev)
- return -ENOMEM;
- chip = iio_priv(indio_dev);
- chip->client = clientp;
- i2c_set_clientdata(clientp, indio_dev);
-
- mutex_init(&chip->als_mutex);
- chip->taos_chip_status = TSL258X_CHIP_UNKNOWN;
- memcpy(chip->taos_config, taos_config, sizeof(chip->taos_config));
-
- for (i = 0; i < TSL258X_MAX_DEVICE_REGS; i++) {
- ret = i2c_smbus_write_byte(clientp,
- (TSL258X_CMD_REG | (TSL258X_CNTRL + i)));
- if (ret < 0) {
- dev_err(&clientp->dev,
- "i2c_smbus_write_byte to cmd reg failed in taos_probe(), err = %d\n",
- ret);
- return ret;
- }
- ret = i2c_smbus_read_byte(clientp);
- if (ret < 0) {
- dev_err(&clientp->dev,
- "i2c_smbus_read_byte from reg failed in taos_probe(), err = %d\n",
- ret);
- return ret;
- }
- buf[i] = ret;
- }
-
- if (!taos_tsl258x_device(buf)) {
- dev_info(&clientp->dev,
- "i2c device found but does not match expected id in taos_probe()\n");
- return -EINVAL;
- }
-
- ret = i2c_smbus_write_byte(clientp, (TSL258X_CMD_REG | TSL258X_CNTRL));
- if (ret < 0) {
- dev_err(&clientp->dev,
- "i2c_smbus_write_byte() to cmd reg failed in taos_probe(), err = %d\n",
- ret);
- return ret;
- }
-
- indio_dev->info = &tsl2583_info;
- indio_dev->dev.parent = &clientp->dev;
- indio_dev->modes = INDIO_DIRECT_MODE;
- indio_dev->name = chip->client->name;
- ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev);
- if (ret) {
- dev_err(&clientp->dev, "iio registration failed\n");
- return ret;
- }
-
- /* Load up the V2 defaults (these are hard coded defaults for now) */
- taos_defaults(chip);
-
- /* Make sure the chip is on */
- taos_chip_on(indio_dev);
-
- dev_info(&clientp->dev, "Light sensor found.\n");
- return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int taos_suspend(struct device *dev)
-{
- struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
- struct tsl2583_chip *chip = iio_priv(indio_dev);
- int ret = 0;
-
- mutex_lock(&chip->als_mutex);
-
- if (chip->taos_chip_status == TSL258X_CHIP_WORKING) {
- ret = taos_chip_off(indio_dev);
- chip->taos_chip_status = TSL258X_CHIP_SUSPENDED;
- }
-
- mutex_unlock(&chip->als_mutex);
- return ret;
-}
-
-static int taos_resume(struct device *dev)
-{
- struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
- struct tsl2583_chip *chip = iio_priv(indio_dev);
- int ret = 0;
-
- mutex_lock(&chip->als_mutex);
-
- if (chip->taos_chip_status == TSL258X_CHIP_SUSPENDED)
- ret = taos_chip_on(indio_dev);
-
- mutex_unlock(&chip->als_mutex);
- return ret;
-}
-
-static SIMPLE_DEV_PM_OPS(taos_pm_ops, taos_suspend, taos_resume);
-#define TAOS_PM_OPS (&taos_pm_ops)
-#else
-#define TAOS_PM_OPS NULL
-#endif
-
-static struct i2c_device_id taos_idtable[] = {
- { "tsl2580", 0 },
- { "tsl2581", 1 },
- { "tsl2583", 2 },
- {}
-};
-MODULE_DEVICE_TABLE(i2c, taos_idtable);
-
-/* Driver definition */
-static struct i2c_driver taos_driver = {
- .driver = {
- .name = "tsl2583",
- .pm = TAOS_PM_OPS,
- },
- .id_table = taos_idtable,
- .probe = taos_probe,
-};
-module_i2c_driver(taos_driver);
-
-MODULE_AUTHOR("J. August Brenner<jbrenner@taosinc.com>");
-MODULE_DESCRIPTION("TAOS tsl2583 ambient light sensor driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c
index ebb8a1993303..3af8f77b8e41 100644
--- a/drivers/staging/iio/meter/ade7758_core.c
+++ b/drivers/staging/iio/meter/ade7758_core.c
@@ -465,38 +465,26 @@ err_ret:
return ret;
}
-static ssize_t ade7758_read_frequency(struct device *dev,
- struct device_attribute *attr, char *buf)
+static int ade7758_read_samp_freq(struct device *dev, int *val)
{
int ret;
u8 t;
- int sps;
ret = ade7758_spi_read_reg_8(dev, ADE7758_WAVMODE, &t);
if (ret)
return ret;
t = (t >> 5) & 0x3;
- sps = 26040 / (1 << t);
+ *val = 26040 / (1 << t);
- return sprintf(buf, "%d SPS\n", sps);
+ return 0;
}
-static ssize_t ade7758_write_frequency(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
+static int ade7758_write_samp_freq(struct device *dev, int val)
{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- u16 val;
int ret;
u8 reg, t;
- ret = kstrtou16(buf, 10, &val);
- if (ret)
- return ret;
-
- mutex_lock(&indio_dev->mlock);
-
switch (val) {
case 26040:
t = 0;
@@ -525,9 +513,49 @@ static ssize_t ade7758_write_frequency(struct device *dev,
ret = ade7758_spi_write_reg_8(dev, ADE7758_WAVMODE, reg);
out:
- mutex_unlock(&indio_dev->mlock);
+ return ret;
+}
- return ret ? ret : len;
+static int ade7758_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val,
+ int *val2,
+ long mask)
+{
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ mutex_lock(&indio_dev->mlock);
+ ret = ade7758_read_samp_freq(&indio_dev->dev, val);
+ mutex_unlock(&indio_dev->mlock);
+ return ret;
+ default:
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static int ade7758_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val, int val2, long mask)
+{
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ if (val2)
+ return -EINVAL;
+ mutex_lock(&indio_dev->mlock);
+ ret = ade7758_write_samp_freq(&indio_dev->dev, val);
+ mutex_unlock(&indio_dev->mlock);
+ return ret;
+ default:
+ return -EINVAL;
+ }
+
+ return ret;
}
static IIO_DEV_ATTR_TEMP_RAW(ade7758_read_8bit);
@@ -553,17 +581,12 @@ static IIO_DEV_ATTR_BVAHR(ade7758_read_16bit,
static IIO_DEV_ATTR_CVAHR(ade7758_read_16bit,
ADE7758_CVAHR);
-static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
- ade7758_read_frequency,
- ade7758_write_frequency);
-
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("26040 13020 6510 3255");
static struct attribute *ade7758_attributes[] = {
&iio_dev_attr_in_temp_raw.dev_attr.attr,
&iio_const_attr_in_temp_offset.dev_attr.attr,
&iio_const_attr_in_temp_scale.dev_attr.attr,
- &iio_dev_attr_sampling_frequency.dev_attr.attr,
&iio_const_attr_sampling_frequency_available.dev_attr.attr,
&iio_dev_attr_awatthr.dev_attr.attr,
&iio_dev_attr_bwatthr.dev_attr.attr,
@@ -611,6 +634,7 @@ static const struct iio_chan_spec ade7758_channels[] = {
.type = IIO_VOLTAGE,
.indexed = 1,
.channel = 0,
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
.address = AD7758_WT(AD7758_PHASE_A, AD7758_VOLTAGE),
.scan_index = 0,
.scan_type = {
@@ -622,6 +646,7 @@ static const struct iio_chan_spec ade7758_channels[] = {
.type = IIO_CURRENT,
.indexed = 1,
.channel = 0,
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
.address = AD7758_WT(AD7758_PHASE_A, AD7758_CURRENT),
.scan_index = 1,
.scan_type = {
@@ -634,6 +659,7 @@ static const struct iio_chan_spec ade7758_channels[] = {
.indexed = 1,
.channel = 0,
.extend_name = "apparent",
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
.address = AD7758_WT(AD7758_PHASE_A, AD7758_APP_PWR),
.scan_index = 2,
.scan_type = {
@@ -646,6 +672,7 @@ static const struct iio_chan_spec ade7758_channels[] = {
.indexed = 1,
.channel = 0,
.extend_name = "active",
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
.address = AD7758_WT(AD7758_PHASE_A, AD7758_ACT_PWR),
.scan_index = 3,
.scan_type = {
@@ -658,6 +685,7 @@ static const struct iio_chan_spec ade7758_channels[] = {
.indexed = 1,
.channel = 0,
.extend_name = "reactive",
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
.address = AD7758_WT(AD7758_PHASE_A, AD7758_REACT_PWR),
.scan_index = 4,
.scan_type = {
@@ -669,6 +697,7 @@ static const struct iio_chan_spec ade7758_channels[] = {
.type = IIO_VOLTAGE,
.indexed = 1,
.channel = 1,
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
.address = AD7758_WT(AD7758_PHASE_B, AD7758_VOLTAGE),
.scan_index = 5,
.scan_type = {
@@ -680,6 +709,7 @@ static const struct iio_chan_spec ade7758_channels[] = {
.type = IIO_CURRENT,
.indexed = 1,
.channel = 1,
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
.address = AD7758_WT(AD7758_PHASE_B, AD7758_CURRENT),
.scan_index = 6,
.scan_type = {
@@ -692,6 +722,7 @@ static const struct iio_chan_spec ade7758_channels[] = {
.indexed = 1,
.channel = 1,
.extend_name = "apparent",
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
.address = AD7758_WT(AD7758_PHASE_B, AD7758_APP_PWR),
.scan_index = 7,
.scan_type = {
@@ -704,6 +735,7 @@ static const struct iio_chan_spec ade7758_channels[] = {
.indexed = 1,
.channel = 1,
.extend_name = "active",
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
.address = AD7758_WT(AD7758_PHASE_B, AD7758_ACT_PWR),
.scan_index = 8,
.scan_type = {
@@ -716,6 +748,7 @@ static const struct iio_chan_spec ade7758_channels[] = {
.indexed = 1,
.channel = 1,
.extend_name = "reactive",
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
.address = AD7758_WT(AD7758_PHASE_B, AD7758_REACT_PWR),
.scan_index = 9,
.scan_type = {
@@ -727,6 +760,7 @@ static const struct iio_chan_spec ade7758_channels[] = {
.type = IIO_VOLTAGE,
.indexed = 1,
.channel = 2,
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
.address = AD7758_WT(AD7758_PHASE_C, AD7758_VOLTAGE),
.scan_index = 10,
.scan_type = {
@@ -738,6 +772,7 @@ static const struct iio_chan_spec ade7758_channels[] = {
.type = IIO_CURRENT,
.indexed = 1,
.channel = 2,
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
.address = AD7758_WT(AD7758_PHASE_C, AD7758_CURRENT),
.scan_index = 11,
.scan_type = {
@@ -750,6 +785,7 @@ static const struct iio_chan_spec ade7758_channels[] = {
.indexed = 1,
.channel = 2,
.extend_name = "apparent",
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
.address = AD7758_WT(AD7758_PHASE_C, AD7758_APP_PWR),
.scan_index = 12,
.scan_type = {
@@ -762,6 +798,7 @@ static const struct iio_chan_spec ade7758_channels[] = {
.indexed = 1,
.channel = 2,
.extend_name = "active",
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
.address = AD7758_WT(AD7758_PHASE_C, AD7758_ACT_PWR),
.scan_index = 13,
.scan_type = {
@@ -774,6 +811,7 @@ static const struct iio_chan_spec ade7758_channels[] = {
.indexed = 1,
.channel = 2,
.extend_name = "reactive",
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
.address = AD7758_WT(AD7758_PHASE_C, AD7758_REACT_PWR),
.scan_index = 14,
.scan_type = {
@@ -787,6 +825,8 @@ static const struct iio_chan_spec ade7758_channels[] = {
static const struct iio_info ade7758_info = {
.attrs = &ade7758_attribute_group,
+ .read_raw = &ade7758_read_raw,
+ .write_raw = &ade7758_write_raw,
.driver_module = THIS_MODULE,
};
diff --git a/drivers/staging/iio/ring_hw.h b/drivers/staging/iio/ring_hw.h
deleted file mode 100644
index 75bf47bfee78..000000000000
--- a/drivers/staging/iio/ring_hw.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * ring_hw.h - common functionality for iio hardware ring buffers
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * Copyright (c) 2009 Jonathan Cameron <jic23@kernel.org>
- *
- */
-
-#ifndef _RING_HW_H_
-#define _RING_HW_H_
-
-/**
- * struct iio_hw_ring_buffer- hardware ring buffer
- * @buf: generic ring buffer elements
- * @private: device specific data
- */
-struct iio_hw_buffer {
- struct iio_buffer buf;
- void *private;
-};
-
-#define iio_to_hw_buf(r) container_of(r, struct iio_hw_buffer, buf)
-
-#endif /* _RING_HW_H_ */