diff options
Diffstat (limited to 'drivers/staging/iio/accel')
29 files changed, 463 insertions, 3719 deletions
diff --git a/drivers/staging/iio/accel/Kconfig b/drivers/staging/iio/accel/Kconfig index 5ab71670b70f..2b54430f2d99 100644 --- a/drivers/staging/iio/accel/Kconfig +++ b/drivers/staging/iio/accel/Kconfig @@ -6,8 +6,8 @@ menu "Accelerometers" config ADIS16201 tristate "Analog Devices ADIS16201 Dual-Axis Digital Inclinometer and Accelerometer" depends on SPI - select IIO_TRIGGER if IIO_BUFFER - select IIO_SW_RING if IIO_BUFFER + select IIO_ADIS_LIB + select IIO_ADIS_LIB_BUFFER if IIO_BUFFER help Say yes here to build support for Analog Devices adis16201 dual-axis digital inclinometer and accelerometer. @@ -15,8 +15,8 @@ config ADIS16201 config ADIS16203 tristate "Analog Devices ADIS16203 Programmable 360 Degrees Inclinometer" depends on SPI - select IIO_TRIGGER if IIO_BUFFER - select IIO_SW_RING if IIO_BUFFER + select IIO_ADIS_LIB + select IIO_ADIS_LIB_BUFFER if IIO_BUFFER help Say yes here to build support for Analog Devices adis16203 Programmable 360 Degrees Inclinometer. @@ -24,8 +24,8 @@ config ADIS16203 config ADIS16204 tristate "Analog Devices ADIS16204 Programmable High-g Digital Impact Sensor and Recorder" depends on SPI - select IIO_TRIGGER if IIO_BUFFER - select IIO_SW_RING if IIO_BUFFER + select IIO_ADIS_LIB + select IIO_ADIS_LIB_BUFFER if IIO_BUFFER help Say yes here to build support for Analog Devices adis16204 Programmable High-g Digital Impact Sensor and Recorder. @@ -33,8 +33,8 @@ config ADIS16204 config ADIS16209 tristate "Analog Devices ADIS16209 Dual-Axis Digital Inclinometer and Accelerometer" depends on SPI - select IIO_TRIGGER if IIO_BUFFER - select IIO_SW_RING if IIO_BUFFER + select IIO_ADIS_LIB + select IIO_ADIS_LIB_BUFFER if IIO_BUFFER help Say yes here to build support for Analog Devices adis16209 dual-axis digital inclinometer and accelerometer. @@ -42,6 +42,7 @@ config ADIS16209 config ADIS16220 tristate "Analog Devices ADIS16220 Programmable Digital Vibration Sensor" depends on SPI + select IIO_ADIS_LIB help Say yes here to build support for Analog Devices adis16220 programmable digital vibration sensor. @@ -49,8 +50,8 @@ config ADIS16220 config ADIS16240 tristate "Analog Devices ADIS16240 Programmable Impact Sensor and Recorder" depends on SPI - select IIO_TRIGGER if IIO_BUFFER - select IIO_SW_RING if IIO_BUFFER + select IIO_ADIS_LIB + select IIO_ADIS_LIB_BUFFER if IIO_BUFFER help Say yes here to build support for Analog Devices adis16240 programmable impact Sensor and recorder. diff --git a/drivers/staging/iio/accel/Makefile b/drivers/staging/iio/accel/Makefile index 95c66661e702..8e7ee0368519 100644 --- a/drivers/staging/iio/accel/Makefile +++ b/drivers/staging/iio/accel/Makefile @@ -3,26 +3,21 @@ # adis16201-y := adis16201_core.o -adis16201-$(CONFIG_IIO_BUFFER) += adis16201_ring.o adis16201_trigger.o obj-$(CONFIG_ADIS16201) += adis16201.o adis16203-y := adis16203_core.o -adis16203-$(CONFIG_IIO_BUFFER) += adis16203_ring.o adis16203_trigger.o obj-$(CONFIG_ADIS16203) += adis16203.o adis16204-y := adis16204_core.o -adis16204-$(CONFIG_IIO_BUFFER) += adis16204_ring.o adis16204_trigger.o obj-$(CONFIG_ADIS16204) += adis16204.o adis16209-y := adis16209_core.o -adis16209-$(CONFIG_IIO_BUFFER) += adis16209_ring.o adis16209_trigger.o obj-$(CONFIG_ADIS16209) += adis16209.o adis16220-y := adis16220_core.o obj-$(CONFIG_ADIS16220) += adis16220.o adis16240-y := adis16240_core.o -adis16240-$(CONFIG_IIO_BUFFER) += adis16240_ring.o adis16240_trigger.o obj-$(CONFIG_ADIS16240) += adis16240.o obj-$(CONFIG_KXSD9) += kxsd9.o diff --git a/drivers/staging/iio/accel/adis16201.h b/drivers/staging/iio/accel/adis16201.h index 72750f7f3a81..8747de5a9805 100644 --- a/drivers/staging/iio/accel/adis16201.h +++ b/drivers/staging/iio/accel/adis16201.h @@ -3,9 +3,6 @@ #define ADIS16201_STARTUP_DELAY 220 /* ms */ -#define ADIS16201_READ_REG(a) a -#define ADIS16201_WRITE_REG(a) ((a) | 0x80) - #define ADIS16201_FLASH_CNT 0x00 /* Flash memory write count */ #define ADIS16201_SUPPLY_OUT 0x02 /* Output, power supply */ #define ADIS16201_XACCL_OUT 0x04 /* Output, x-axis accelerometer */ @@ -36,8 +33,6 @@ #define ADIS16201_DIAG_STAT 0x3C /* Diagnostics, system status register */ #define ADIS16201_GLOB_CMD 0x3E /* Operation, system command register */ -#define ADIS16201_OUTPUTS 7 - /* MSC_CTRL */ #define ADIS16201_MSC_CTRL_SELF_TEST_EN (1 << 8) /* Self-test enable */ #define ADIS16201_MSC_CTRL_DATA_RDY_EN (1 << 2) /* Data-ready enable: 1 = enabled, 0 = disabled */ @@ -47,95 +42,25 @@ /* DIAG_STAT */ #define ADIS16201_DIAG_STAT_ALARM2 (1<<9) /* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */ #define ADIS16201_DIAG_STAT_ALARM1 (1<<8) /* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */ -#define ADIS16201_DIAG_STAT_SPI_FAIL (1<<3) /* SPI communications failure */ -#define ADIS16201_DIAG_STAT_FLASH_UPT (1<<2) /* Flash update failure */ -#define ADIS16201_DIAG_STAT_POWER_HIGH (1<<1) /* Power supply above 3.625 V */ -#define ADIS16201_DIAG_STAT_POWER_LOW (1<<0) /* Power supply below 3.15 V */ +#define ADIS16201_DIAG_STAT_SPI_FAIL_BIT 3 /* SPI communications failure */ +#define ADIS16201_DIAG_STAT_FLASH_UPT_BIT 2 /* Flash update failure */ +#define ADIS16201_DIAG_STAT_POWER_HIGH_BIT 1 /* Power supply above 3.625 V */ +#define ADIS16201_DIAG_STAT_POWER_LOW_BIT 0 /* Power supply below 3.15 V */ /* GLOB_CMD */ #define ADIS16201_GLOB_CMD_SW_RESET (1<<7) #define ADIS16201_GLOB_CMD_FACTORY_CAL (1<<1) -#define ADIS16201_MAX_TX 14 -#define ADIS16201_MAX_RX 14 - #define ADIS16201_ERROR_ACTIVE (1<<14) -/** - * struct adis16201_state - device instance specific data - * @us: actual spi_device - * @trig: data ready trigger registered with iio - * @tx: transmit buffer - * @rx: receive buffer - * @buf_lock: mutex to protect tx and rx - **/ -struct adis16201_state { - struct spi_device *us; - struct iio_trigger *trig; - struct mutex buf_lock; - u8 tx[14] ____cacheline_aligned; - u8 rx[14]; -}; - -int adis16201_set_irq(struct iio_dev *indio_dev, bool enable); - enum adis16201_scan { - ADIS16201_SCAN_SUPPLY, ADIS16201_SCAN_ACC_X, ADIS16201_SCAN_ACC_Y, - ADIS16201_SCAN_AUX_ADC, - ADIS16201_SCAN_TEMP, ADIS16201_SCAN_INCLI_X, ADIS16201_SCAN_INCLI_Y, + ADIS16201_SCAN_SUPPLY, + ADIS16201_SCAN_AUX_ADC, + ADIS16201_SCAN_TEMP, }; -#ifdef CONFIG_IIO_BUFFER -void adis16201_remove_trigger(struct iio_dev *indio_dev); -int adis16201_probe_trigger(struct iio_dev *indio_dev); - -ssize_t adis16201_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf); - -int adis16201_configure_ring(struct iio_dev *indio_dev); -void adis16201_unconfigure_ring(struct iio_dev *indio_dev); - -#else /* CONFIG_IIO_BUFFER */ - -static inline void adis16201_remove_trigger(struct iio_dev *indio_dev) -{ -} - -static inline int adis16201_probe_trigger(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline ssize_t -adis16201_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return 0; -} - -static int adis16201_configure_ring(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline void adis16201_unconfigure_ring(struct iio_dev *indio_dev) -{ -} - -static inline int adis16201_initialize_ring(struct iio_ring_buffer *ring) -{ - return 0; -} - -static inline void adis16201_uninitialize_ring(struct iio_ring_buffer *ring) -{ -} - -#endif /* CONFIG_IIO_BUFFER */ #endif /* SPI_ADIS16201_H_ */ diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c index b12ca68cd9e4..9e5791ff2a04 100644 --- a/drivers/staging/iio/accel/adis16201_core.c +++ b/drivers/staging/iio/accel/adis16201_core.c @@ -18,258 +18,15 @@ #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> #include <linux/iio/buffer.h> +#include <linux/iio/imu/adis.h> #include "adis16201.h" -enum adis16201_chan { - in_supply, - temp, - accel_x, - accel_y, - incli_x, - incli_y, - in_aux, -}; - -/** - * adis16201_spi_write_reg_8() - write single byte to a register - * @dev: device associated with child of actual device (iio_dev or iio_trig) - * @reg_address: the address of the register to be written - * @val: the value to write - **/ -static int adis16201_spi_write_reg_8(struct iio_dev *indio_dev, - u8 reg_address, - u8 val) -{ - int ret; - struct adis16201_state *st = iio_priv(indio_dev); - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16201_WRITE_REG(reg_address); - st->tx[1] = val; - - ret = spi_write(st->us, st->tx, 2); - mutex_unlock(&st->buf_lock); - - return ret; -} - -/** - * adis16201_spi_write_reg_16() - write 2 bytes to a pair of registers - * @indio_dev: iio device associated with child of actual device - * @reg_address: the address of the lower of the two registers. Second register - * is assumed to have address one greater. - * @val: value to be written - **/ -static int adis16201_spi_write_reg_16(struct iio_dev *indio_dev, - u8 lower_reg_address, - u16 value) -{ - int ret; - struct spi_message msg; - struct adis16201_state *st = iio_priv(indio_dev); - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - }, { - .tx_buf = st->tx + 2, - .bits_per_word = 8, - .len = 2, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16201_WRITE_REG(lower_reg_address); - st->tx[1] = value & 0xFF; - st->tx[2] = ADIS16201_WRITE_REG(lower_reg_address + 1); - st->tx[3] = (value >> 8) & 0xFF; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); - mutex_unlock(&st->buf_lock); - - return ret; -} - -/** - * adis16201_spi_read_reg_16() - read 2 bytes from a 16-bit register - * @indio_dev: iio device associated with child of actual device - * @reg_address: the address of the lower of the two registers. Second register - * is assumed to have address one greater. - * @val: somewhere to pass back the value read - **/ -static int adis16201_spi_read_reg_16(struct iio_dev *indio_dev, - u8 lower_reg_address, - u16 *val) -{ - struct spi_message msg; - struct adis16201_state *st = iio_priv(indio_dev); - int ret; - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .delay_usecs = 20, - }, { - .rx_buf = st->rx, - .bits_per_word = 8, - .len = 2, - .delay_usecs = 20, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16201_READ_REG(lower_reg_address); - st->tx[1] = 0; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); - if (ret) { - dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X", - lower_reg_address); - goto error_ret; - } - *val = (st->rx[0] << 8) | st->rx[1]; - -error_ret: - mutex_unlock(&st->buf_lock); - return ret; -} - -static int adis16201_reset(struct iio_dev *indio_dev) -{ - int ret; - struct adis16201_state *st = iio_priv(indio_dev); - - ret = adis16201_spi_write_reg_8(indio_dev, - ADIS16201_GLOB_CMD, - ADIS16201_GLOB_CMD_SW_RESET); - if (ret) - dev_err(&st->us->dev, "problem resetting device"); - - return ret; -} - -int adis16201_set_irq(struct iio_dev *indio_dev, bool enable) -{ - int ret = 0; - u16 msc; - - ret = adis16201_spi_read_reg_16(indio_dev, ADIS16201_MSC_CTRL, &msc); - if (ret) - goto error_ret; - - msc |= ADIS16201_MSC_CTRL_ACTIVE_HIGH; - msc &= ~ADIS16201_MSC_CTRL_DATA_RDY_DIO1; - if (enable) - msc |= ADIS16201_MSC_CTRL_DATA_RDY_EN; - else - msc &= ~ADIS16201_MSC_CTRL_DATA_RDY_EN; - - ret = adis16201_spi_write_reg_16(indio_dev, ADIS16201_MSC_CTRL, msc); - -error_ret: - return ret; -} - -static int adis16201_check_status(struct iio_dev *indio_dev) -{ - u16 status; - int ret; - - ret = adis16201_spi_read_reg_16(indio_dev, - ADIS16201_DIAG_STAT, &status); - if (ret < 0) { - dev_err(&indio_dev->dev, "Reading status failed\n"); - goto error_ret; - } - ret = status & 0xF; - if (ret) - ret = -EFAULT; - - if (status & ADIS16201_DIAG_STAT_SPI_FAIL) - dev_err(&indio_dev->dev, "SPI failure\n"); - if (status & ADIS16201_DIAG_STAT_FLASH_UPT) - dev_err(&indio_dev->dev, "Flash update failed\n"); - if (status & ADIS16201_DIAG_STAT_POWER_HIGH) - dev_err(&indio_dev->dev, "Power supply above 3.625V\n"); - if (status & ADIS16201_DIAG_STAT_POWER_LOW) - dev_err(&indio_dev->dev, "Power supply below 3.15V\n"); - -error_ret: - return ret; -} - -static int adis16201_self_test(struct iio_dev *indio_dev) -{ - int ret; - ret = adis16201_spi_write_reg_16(indio_dev, - ADIS16201_MSC_CTRL, - ADIS16201_MSC_CTRL_SELF_TEST_EN); - if (ret) { - dev_err(&indio_dev->dev, "problem starting self test"); - goto err_ret; - } - - ret = adis16201_check_status(indio_dev); - -err_ret: - return ret; -} - -static int adis16201_initial_setup(struct iio_dev *indio_dev) -{ - int ret; - struct device *dev = &indio_dev->dev; - - /* Disable IRQ */ - ret = adis16201_set_irq(indio_dev, false); - if (ret) { - dev_err(dev, "disable irq failed"); - goto err_ret; - } - - /* Do self test */ - ret = adis16201_self_test(indio_dev); - if (ret) { - dev_err(dev, "self test failure"); - goto err_ret; - } - - /* Read status register to check the result */ - ret = adis16201_check_status(indio_dev); - if (ret) { - adis16201_reset(indio_dev); - dev_err(dev, "device not playing ball -> reset"); - msleep(ADIS16201_STARTUP_DELAY); - ret = adis16201_check_status(indio_dev); - if (ret) { - dev_err(dev, "giving up"); - goto err_ret; - } - } - -err_ret: - return ret; -} - -static u8 adis16201_addresses[7][2] = { - [in_supply] = { ADIS16201_SUPPLY_OUT, }, - [temp] = { ADIS16201_TEMP_OUT }, - [accel_x] = { ADIS16201_XACCL_OUT, ADIS16201_XACCL_OFFS }, - [accel_y] = { ADIS16201_YACCL_OUT, ADIS16201_YACCL_OFFS }, - [in_aux] = { ADIS16201_AUX_ADC }, - [incli_x] = { ADIS16201_XINCL_OUT }, - [incli_y] = { ADIS16201_YINCL_OUT }, +static const u8 adis16201_addresses[] = { + [ADIS16201_SCAN_ACC_X] = ADIS16201_XACCL_OFFS, + [ADIS16201_SCAN_ACC_Y] = ADIS16201_YACCL_OFFS, + [ADIS16201_SCAN_INCLI_X] = ADIS16201_XINCL_OFFS, + [ADIS16201_SCAN_INCLI_Y] = ADIS16201_YINCL_OFFS, }; static int adis16201_read_raw(struct iio_dev *indio_dev, @@ -277,6 +34,7 @@ static int adis16201_read_raw(struct iio_dev *indio_dev, int *val, int *val2, long mask) { + struct adis *st = iio_priv(indio_dev); int ret; int bits; u8 addr; @@ -284,29 +42,8 @@ static int adis16201_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); - addr = adis16201_addresses[chan->address][0]; - ret = adis16201_spi_read_reg_16(indio_dev, addr, &val16); - if (ret) { - mutex_unlock(&indio_dev->mlock); - return ret; - } - - if (val16 & ADIS16201_ERROR_ACTIVE) { - ret = adis16201_check_status(indio_dev); - if (ret) { - mutex_unlock(&indio_dev->mlock); - return ret; - } - } - val16 = val16 & ((1 << chan->scan_type.realbits) - 1); - if (chan->scan_type.sign == 's') - val16 = (s16)(val16 << - (16 - chan->scan_type.realbits)) >> - (16 - chan->scan_type.realbits); - *val = val16; - mutex_unlock(&indio_dev->mlock); - return IIO_VAL_INT; + return adis_single_conversion(indio_dev, chan, + ADIS16201_ERROR_ACTIVE, val); case IIO_CHAN_INFO_SCALE: switch (chan->type) { case IIO_VOLTAGE: @@ -347,10 +84,10 @@ static int adis16201_read_raw(struct iio_dev *indio_dev, break; default: return -EINVAL; - }; + } mutex_lock(&indio_dev->mlock); - addr = adis16201_addresses[chan->address][1]; - ret = adis16201_spi_read_reg_16(indio_dev, addr, &val16); + addr = adis16201_addresses[chan->scan_index]; + ret = adis_read_reg_16(st, addr, &val16); if (ret) { mutex_unlock(&indio_dev->mlock); return ret; @@ -370,6 +107,7 @@ static int adis16201_write_raw(struct iio_dev *indio_dev, int val2, long mask) { + struct adis *st = iio_priv(indio_dev); int bits; s16 val16; u8 addr; @@ -384,126 +122,63 @@ static int adis16201_write_raw(struct iio_dev *indio_dev, break; default: return -EINVAL; - }; + } val16 = val & ((1 << bits) - 1); - addr = adis16201_addresses[chan->address][1]; - return adis16201_spi_write_reg_16(indio_dev, addr, val16); + addr = adis16201_addresses[chan->scan_index]; + return adis_write_reg_16(st, addr, val16); } return -EINVAL; } static const struct iio_chan_spec adis16201_channels[] = { - { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 0, - .extend_name = "supply", - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - .address = in_supply, - .scan_index = ADIS16201_SCAN_SUPPLY, - .scan_type = { - .sign = 'u', - .realbits = 12, - .storagebits = 16, - }, - }, { - .type = IIO_TEMP, - .indexed = 1, - .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, - .address = temp, - .scan_index = ADIS16201_SCAN_TEMP, - .scan_type = { - .sign = 'u', - .realbits = 12, - .storagebits = 16, - }, - }, { - .type = IIO_ACCEL, - .modified = 1, - .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - .address = accel_x, - .scan_index = ADIS16201_SCAN_ACC_X, - .scan_type = { - .sign = 's', - .realbits = 14, - .storagebits = 16, - }, - }, { - .type = IIO_ACCEL, - .modified = 1, - .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - .address = accel_y, - .scan_index = ADIS16201_SCAN_ACC_Y, - .scan_type = { - .sign = 's', - .realbits = 14, - .storagebits = 16, - }, - }, { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - .address = in_aux, - .scan_index = ADIS16201_SCAN_AUX_ADC, - .scan_type = { - .sign = 'u', - .realbits = 12, - .storagebits = 16, - }, - }, { - .type = IIO_INCLI, - .modified = 1, - .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - .address = incli_x, - .scan_index = ADIS16201_SCAN_INCLI_X, - .scan_type = { - .sign = 's', - .realbits = 14, - .storagebits = 16, - }, - }, { - .type = IIO_INCLI, - .modified = 1, - .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - .address = incli_y, - .scan_index = ADIS16201_SCAN_INCLI_Y, - .scan_type = { - .sign = 's', - .realbits = 14, - .storagebits = 16, - }, - }, + ADIS_SUPPLY_CHAN(ADIS16201_SUPPLY_OUT, ADIS16201_SCAN_SUPPLY, 12), + ADIS_TEMP_CHAN(ADIS16201_TEMP_OUT, ADIS16201_SCAN_TEMP, 12), + ADIS_ACCEL_CHAN(X, ADIS16201_XACCL_OUT, ADIS16201_SCAN_ACC_X, + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, 14), + ADIS_ACCEL_CHAN(Y, ADIS16201_YACCL_OUT, ADIS16201_SCAN_ACC_Y, + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, 14), + ADIS_AUX_ADC_CHAN(ADIS16201_AUX_ADC, ADIS16201_SCAN_AUX_ADC, 12), + ADIS_INCLI_CHAN(X, ADIS16201_XINCL_OUT, ADIS16201_SCAN_INCLI_X, + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, 14), + ADIS_INCLI_CHAN(X, ADIS16201_YINCL_OUT, ADIS16201_SCAN_INCLI_Y, + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, 14), IIO_CHAN_SOFT_TIMESTAMP(7) }; static const struct iio_info adis16201_info = { .read_raw = &adis16201_read_raw, .write_raw = &adis16201_write_raw, + .update_scan_mode = adis_update_scan_mode, .driver_module = THIS_MODULE, }; -static int __devinit adis16201_probe(struct spi_device *spi) +static const char * const adis16201_status_error_msgs[] = { + [ADIS16201_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure", + [ADIS16201_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed", + [ADIS16201_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V", + [ADIS16201_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 3.15V", +}; + +static const struct adis_data adis16201_data = { + .read_delay = 20, + .msc_ctrl_reg = ADIS16201_MSC_CTRL, + .glob_cmd_reg = ADIS16201_GLOB_CMD, + .diag_stat_reg = ADIS16201_DIAG_STAT, + + .self_test_mask = ADIS16201_MSC_CTRL_SELF_TEST_EN, + .startup_delay = ADIS16201_STARTUP_DELAY, + + .status_error_msgs = adis16201_status_error_msgs, + .status_error_mask = BIT(ADIS16201_DIAG_STAT_SPI_FAIL_BIT) | + BIT(ADIS16201_DIAG_STAT_FLASH_UPT_BIT) | + BIT(ADIS16201_DIAG_STAT_POWER_HIGH_BIT) | + BIT(ADIS16201_DIAG_STAT_POWER_LOW_BIT), +}; + +static int adis16201_probe(struct spi_device *spi) { int ret; - struct adis16201_state *st; + struct adis *st; struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ @@ -516,9 +191,6 @@ static int __devinit adis16201_probe(struct spi_device *spi) /* this is only used for removal purposes */ spi_set_drvdata(spi, indio_dev); - st->us = spi; - mutex_init(&st->buf_lock); - indio_dev->name = spi->dev.driver->name; indio_dev->dev.parent = &spi->dev; indio_dev->info = &adis16201_info; @@ -527,54 +199,38 @@ static int __devinit adis16201_probe(struct spi_device *spi) indio_dev->num_channels = ARRAY_SIZE(adis16201_channels); indio_dev->modes = INDIO_DIRECT_MODE; - ret = adis16201_configure_ring(indio_dev); + ret = adis_init(st, indio_dev, spi, &adis16201_data); + if (ret) + goto error_free_dev; + ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL); if (ret) goto error_free_dev; - - ret = iio_buffer_register(indio_dev, - adis16201_channels, - ARRAY_SIZE(adis16201_channels)); - if (ret) { - printk(KERN_ERR "failed to initialize the ring\n"); - goto error_unreg_ring_funcs; - } - - if (spi->irq) { - ret = adis16201_probe_trigger(indio_dev); - if (ret) - goto error_uninitialize_ring; - } /* Get the device into a sane initial state */ - ret = adis16201_initial_setup(indio_dev); + ret = adis_initial_startup(st); if (ret) - goto error_remove_trigger; + goto error_cleanup_buffer_trigger; ret = iio_device_register(indio_dev); if (ret < 0) - goto error_remove_trigger; + goto error_cleanup_buffer_trigger; return 0; -error_remove_trigger: - adis16201_remove_trigger(indio_dev); -error_uninitialize_ring: - iio_buffer_unregister(indio_dev); -error_unreg_ring_funcs: - adis16201_unconfigure_ring(indio_dev); +error_cleanup_buffer_trigger: + adis_cleanup_buffer_and_trigger(st, indio_dev); error_free_dev: iio_device_free(indio_dev); error_ret: return ret; } -static int __devexit adis16201_remove(struct spi_device *spi) +static int adis16201_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct adis *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); - adis16201_remove_trigger(indio_dev); - iio_buffer_unregister(indio_dev); - adis16201_unconfigure_ring(indio_dev); + adis_cleanup_buffer_and_trigger(st, indio_dev); iio_device_free(indio_dev); return 0; @@ -586,7 +242,7 @@ static struct spi_driver adis16201_driver = { .owner = THIS_MODULE, }, .probe = adis16201_probe, - .remove = __devexit_p(adis16201_remove), + .remove = adis16201_remove, }; module_spi_driver(adis16201_driver); diff --git a/drivers/staging/iio/accel/adis16201_ring.c b/drivers/staging/iio/accel/adis16201_ring.c deleted file mode 100644 index 97c09f0c26ae..000000000000 --- a/drivers/staging/iio/accel/adis16201_ring.c +++ /dev/null @@ -1,136 +0,0 @@ -#include <linux/export.h> -#include <linux/interrupt.h> -#include <linux/mutex.h> -#include <linux/kernel.h> -#include <linux/spi/spi.h> -#include <linux/slab.h> - -#include <linux/iio/iio.h> -#include "../ring_sw.h" -#include <linux/iio/trigger_consumer.h> -#include "adis16201.h" - - -/** - * adis16201_read_ring_data() read data registers which will be placed into ring - * @dev: device associated with child of actual device (iio_dev or iio_trig) - * @rx: somewhere to pass back the value read - **/ -static int adis16201_read_ring_data(struct iio_dev *indio_dev, u8 *rx) -{ - struct spi_message msg; - struct adis16201_state *st = iio_priv(indio_dev); - struct spi_transfer xfers[ADIS16201_OUTPUTS + 1]; - int ret; - int i; - - mutex_lock(&st->buf_lock); - - spi_message_init(&msg); - - memset(xfers, 0, sizeof(xfers)); - for (i = 0; i <= ADIS16201_OUTPUTS; i++) { - xfers[i].bits_per_word = 8; - xfers[i].cs_change = 1; - xfers[i].len = 2; - xfers[i].delay_usecs = 20; - if (i < ADIS16201_OUTPUTS) { - xfers[i].tx_buf = st->tx + 2 * i; - st->tx[2 * i] = ADIS16201_READ_REG(ADIS16201_SUPPLY_OUT + - 2 * i); - st->tx[2 * i + 1] = 0; - } - if (i >= 1) - xfers[i].rx_buf = rx + 2 * (i - 1); - spi_message_add_tail(&xfers[i], &msg); - } - - ret = spi_sync(st->us, &msg); - if (ret) - dev_err(&st->us->dev, "problem when burst reading"); - - mutex_unlock(&st->buf_lock); - - return ret; -} - -/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device - * specific to be rolled into the core. - */ -static irqreturn_t adis16201_trigger_handler(int irq, void *p) -{ - struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->indio_dev; - struct adis16201_state *st = iio_priv(indio_dev); - - int i = 0; - s16 *data; - - data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); - if (data == NULL) { - dev_err(&st->us->dev, "memory alloc failed in ring bh"); - goto done; - } - - if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) - && adis16201_read_ring_data(indio_dev, st->rx) >= 0) - for (; i < bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength); i++) - data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2])); - - /* Guaranteed to be aligned with 8 byte boundary */ - if (indio_dev->scan_timestamp) - *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - - iio_push_to_buffer(indio_dev->buffer, (u8 *)data); - - kfree(data); -done: - iio_trigger_notify_done(indio_dev->trig); - - return IRQ_HANDLED; -} - -void adis16201_unconfigure_ring(struct iio_dev *indio_dev) -{ - iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_sw_rb_free(indio_dev->buffer); -} - -static const struct iio_buffer_setup_ops adis16201_ring_setup_ops = { - .preenable = &iio_sw_buffer_preenable, - .postenable = &iio_triggered_buffer_postenable, - .predisable = &iio_triggered_buffer_predisable, -}; - -int adis16201_configure_ring(struct iio_dev *indio_dev) -{ - int ret = 0; - struct iio_buffer *ring; - - ring = iio_sw_rb_allocate(indio_dev); - if (!ring) { - ret = -ENOMEM; - return ret; - } - indio_dev->buffer = ring; - ring->scan_timestamp = true; - indio_dev->setup_ops = &adis16201_ring_setup_ops; - - indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, - &adis16201_trigger_handler, - IRQF_ONESHOT, - indio_dev, - "adis16201_consumer%d", - indio_dev->id); - if (indio_dev->pollfunc == NULL) { - ret = -ENOMEM; - goto error_iio_sw_rb_free; - } - - indio_dev->modes |= INDIO_BUFFER_TRIGGERED; - return 0; -error_iio_sw_rb_free: - iio_sw_rb_free(indio_dev->buffer); - return ret; -} diff --git a/drivers/staging/iio/accel/adis16201_trigger.c b/drivers/staging/iio/accel/adis16201_trigger.c deleted file mode 100644 index 96fdabbac201..000000000000 --- a/drivers/staging/iio/accel/adis16201_trigger.c +++ /dev/null @@ -1,71 +0,0 @@ -#include <linux/interrupt.h> -#include <linux/kernel.h> -#include <linux/spi/spi.h> -#include <linux/export.h> - -#include <linux/iio/iio.h> -#include <linux/iio/trigger.h> -#include "adis16201.h" - -/** - * adis16201_data_rdy_trigger_set_state() set datardy interrupt state - **/ -static int adis16201_data_rdy_trigger_set_state(struct iio_trigger *trig, - bool state) -{ - struct iio_dev *indio_dev = trig->private_data; - - dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); - return adis16201_set_irq(indio_dev, state); -} - -static const struct iio_trigger_ops adis16201_trigger_ops = { - .owner = THIS_MODULE, - .set_trigger_state = &adis16201_data_rdy_trigger_set_state, -}; - -int adis16201_probe_trigger(struct iio_dev *indio_dev) -{ - int ret; - struct adis16201_state *st = iio_priv(indio_dev); - - st->trig = iio_trigger_alloc("adis16201-dev%d", indio_dev->id); - if (st->trig == NULL) { - ret = -ENOMEM; - goto error_ret; - } - ret = request_irq(st->us->irq, - &iio_trigger_generic_data_rdy_poll, - IRQF_TRIGGER_RISING, - "adis16201", - st->trig); - if (ret) - goto error_free_trig; - st->trig->dev.parent = &st->us->dev; - st->trig->ops = &adis16201_trigger_ops; - st->trig->private_data = indio_dev; - ret = iio_trigger_register(st->trig); - - /* select default trigger */ - indio_dev->trig = st->trig; - if (ret) - goto error_free_irq; - - return 0; - -error_free_irq: - free_irq(st->us->irq, st->trig); -error_free_trig: - iio_trigger_free(st->trig); -error_ret: - return ret; -} - -void adis16201_remove_trigger(struct iio_dev *indio_dev) -{ - struct adis16201_state *state = iio_priv(indio_dev); - - iio_trigger_unregister(state->trig); - free_irq(state->us->irq, state->trig); - iio_trigger_free(state->trig); -} diff --git a/drivers/staging/iio/accel/adis16203.h b/drivers/staging/iio/accel/adis16203.h index 3f96ad3bbd66..acc688d7ea9e 100644 --- a/drivers/staging/iio/accel/adis16203.h +++ b/drivers/staging/iio/accel/adis16203.h @@ -3,9 +3,6 @@ #define ADIS16203_STARTUP_DELAY 220 /* ms */ -#define ADIS16203_READ_REG(a) a -#define ADIS16203_WRITE_REG(a) ((a) | 0x80) - #define ADIS16203_FLASH_CNT 0x00 /* Flash memory write count */ #define ADIS16203_SUPPLY_OUT 0x02 /* Output, power supply */ #define ADIS16203_AUX_ADC 0x08 /* Output, auxiliary ADC input */ @@ -27,8 +24,6 @@ #define ADIS16203_DIAG_STAT 0x3C /* Diagnostics, system status register */ #define ADIS16203_GLOB_CMD 0x3E /* Operation, system command register */ -#define ADIS16203_OUTPUTS 5 - /* MSC_CTRL */ #define ADIS16203_MSC_CTRL_PWRUP_SELF_TEST (1 << 10) /* Self-test at power-on: 1 = disabled, 0 = enabled */ #define ADIS16203_MSC_CTRL_REVERSE_ROT_EN (1 << 9) /* Reverses rotation of both inclination outputs */ @@ -40,86 +35,25 @@ /* DIAG_STAT */ #define ADIS16203_DIAG_STAT_ALARM2 (1<<9) /* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */ #define ADIS16203_DIAG_STAT_ALARM1 (1<<8) /* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */ -#define ADIS16203_DIAG_STAT_SELFTEST_FAIL (1<<5) /* Self-test diagnostic error flag */ -#define ADIS16203_DIAG_STAT_SPI_FAIL (1<<3) /* SPI communications failure */ -#define ADIS16203_DIAG_STAT_FLASH_UPT (1<<2) /* Flash update failure */ -#define ADIS16203_DIAG_STAT_POWER_HIGH (1<<1) /* Power supply above 3.625 V */ -#define ADIS16203_DIAG_STAT_POWER_LOW (1<<0) /* Power supply below 3.15 V */ +#define ADIS16203_DIAG_STAT_SELFTEST_FAIL_BIT 5 /* Self-test diagnostic error flag */ +#define ADIS16203_DIAG_STAT_SPI_FAIL_BIT 3 /* SPI communications failure */ +#define ADIS16203_DIAG_STAT_FLASH_UPT_BIT 2 /* Flash update failure */ +#define ADIS16203_DIAG_STAT_POWER_HIGH_BIT 1 /* Power supply above 3.625 V */ +#define ADIS16203_DIAG_STAT_POWER_LOW_BIT 0 /* Power supply below 3.15 V */ /* GLOB_CMD */ #define ADIS16203_GLOB_CMD_SW_RESET (1<<7) #define ADIS16203_GLOB_CMD_CLEAR_STAT (1<<4) #define ADIS16203_GLOB_CMD_FACTORY_CAL (1<<1) -#define ADIS16203_MAX_TX 12 -#define ADIS16203_MAX_RX 10 - #define ADIS16203_ERROR_ACTIVE (1<<14) -/** - * struct adis16203_state - device instance specific data - * @us: actual spi_device - * @trig: data ready trigger registered with iio - * @tx: transmit buffer - * @rx: receive buffer - * @buf_lock: mutex to protect tx and rx - **/ -struct adis16203_state { - struct spi_device *us; - struct iio_trigger *trig; - struct mutex buf_lock; - u8 tx[ADIS16203_MAX_TX] ____cacheline_aligned; - u8 rx[ADIS16203_MAX_RX]; -}; - -int adis16203_set_irq(struct iio_dev *indio_dev, bool enable); - enum adis16203_scan { + ADIS16203_SCAN_INCLI_X, + ADIS16203_SCAN_INCLI_Y, ADIS16203_SCAN_SUPPLY, ADIS16203_SCAN_AUX_ADC, ADIS16203_SCAN_TEMP, - ADIS16203_SCAN_INCLI_X, - ADIS16203_SCAN_INCLI_Y, }; -#ifdef CONFIG_IIO_BUFFER -void adis16203_remove_trigger(struct iio_dev *indio_dev); -int adis16203_probe_trigger(struct iio_dev *indio_dev); - -ssize_t adis16203_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf); - -int adis16203_configure_ring(struct iio_dev *indio_dev); -void adis16203_unconfigure_ring(struct iio_dev *indio_dev); - -#else /* CONFIG_IIO_BUFFER */ - -static inline void adis16203_remove_trigger(struct iio_dev *indio_dev) -{ -} - -static inline int adis16203_probe_trigger(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline ssize_t -adis16203_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return 0; -} - -static int adis16203_configure_ring(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline void adis16203_unconfigure_ring(struct iio_dev *indio_dev) -{ -} - -#endif /* CONFIG_IIO_BUFFER */ #endif /* SPI_ADIS16203_H_ */ diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c index e7b3441115ae..8c235273ff13 100644 --- a/drivers/staging/iio/accel/adis16203_core.c +++ b/drivers/staging/iio/accel/adis16203_core.c @@ -1,7 +1,7 @@ /* * ADIS16203 Programmable Digital Vibration Sensor driver * - * Copyright 2010 Analog Devices Inc. + * Copyright 2030 Analog Devices Inc. * * Licensed under the GPL-2 or later. */ @@ -18,254 +18,14 @@ #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> #include <linux/iio/buffer.h> +#include <linux/iio/imu/adis.h> #include "adis16203.h" #define DRIVER_NAME "adis16203" -/** - * adis16203_spi_write_reg_8() - write single byte to a register - * @indio_dev: iio device associated with child of actual device - * @reg_address: the address of the register to be written - * @val: the value to write - **/ -static int adis16203_spi_write_reg_8(struct iio_dev *indio_dev, - u8 reg_address, - u8 val) -{ - int ret; - struct adis16203_state *st = iio_priv(indio_dev); - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16203_WRITE_REG(reg_address); - st->tx[1] = val; - - ret = spi_write(st->us, st->tx, 2); - mutex_unlock(&st->buf_lock); - - return ret; -} - -/** - * adis16203_spi_write_reg_16() - write 2 bytes to a pair of registers - * @indio_dev: iio device associated with child of actual device - * @reg_address: the address of the lower of the two registers. Second register - * is assumed to have address one greater. - * @val: value to be written - **/ -static int adis16203_spi_write_reg_16(struct iio_dev *indio_dev, - u8 lower_reg_address, - u16 value) -{ - int ret; - struct spi_message msg; - struct adis16203_state *st = iio_priv(indio_dev); - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - }, { - .tx_buf = st->tx + 2, - .bits_per_word = 8, - .len = 2, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16203_WRITE_REG(lower_reg_address); - st->tx[1] = value & 0xFF; - st->tx[2] = ADIS16203_WRITE_REG(lower_reg_address + 1); - st->tx[3] = (value >> 8) & 0xFF; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); - mutex_unlock(&st->buf_lock); - - return ret; -} - -/** - * adis16203_spi_read_reg_16() - read 2 bytes from a 16-bit register - * @indio_dev: iio device associated with child of actual device - * @reg_address: the address of the lower of the two registers. Second register - * is assumed to have address one greater. - * @val: somewhere to pass back the value read - **/ -static int adis16203_spi_read_reg_16(struct iio_dev *indio_dev, - u8 lower_reg_address, - u16 *val) -{ - struct spi_message msg; - struct adis16203_state *st = iio_priv(indio_dev); - int ret; - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .delay_usecs = 20, - }, { - .rx_buf = st->rx, - .bits_per_word = 8, - .len = 2, - .delay_usecs = 20, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16203_READ_REG(lower_reg_address); - st->tx[1] = 0; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); - if (ret) { - dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X", - lower_reg_address); - goto error_ret; - } - *val = (st->rx[0] << 8) | st->rx[1]; - -error_ret: - mutex_unlock(&st->buf_lock); - return ret; -} - -static int adis16203_check_status(struct iio_dev *indio_dev) -{ - u16 status; - int ret; - - ret = adis16203_spi_read_reg_16(indio_dev, - ADIS16203_DIAG_STAT, - &status); - if (ret < 0) { - dev_err(&indio_dev->dev, "Reading status failed\n"); - goto error_ret; - } - ret = status & 0x1F; - - if (status & ADIS16203_DIAG_STAT_SELFTEST_FAIL) - dev_err(&indio_dev->dev, "Self test failure\n"); - if (status & ADIS16203_DIAG_STAT_SPI_FAIL) - dev_err(&indio_dev->dev, "SPI failure\n"); - if (status & ADIS16203_DIAG_STAT_FLASH_UPT) - dev_err(&indio_dev->dev, "Flash update failed\n"); - if (status & ADIS16203_DIAG_STAT_POWER_HIGH) - dev_err(&indio_dev->dev, "Power supply above 3.625V\n"); - if (status & ADIS16203_DIAG_STAT_POWER_LOW) - dev_err(&indio_dev->dev, "Power supply below 3.15V\n"); - -error_ret: - return ret; -} - -static int adis16203_reset(struct iio_dev *indio_dev) -{ - int ret; - ret = adis16203_spi_write_reg_8(indio_dev, - ADIS16203_GLOB_CMD, - ADIS16203_GLOB_CMD_SW_RESET); - if (ret) - dev_err(&indio_dev->dev, "problem resetting device"); - - return ret; -} - -int adis16203_set_irq(struct iio_dev *indio_dev, bool enable) -{ - int ret = 0; - u16 msc; - - ret = adis16203_spi_read_reg_16(indio_dev, ADIS16203_MSC_CTRL, &msc); - if (ret) - goto error_ret; - - msc |= ADIS16203_MSC_CTRL_ACTIVE_HIGH; - msc &= ~ADIS16203_MSC_CTRL_DATA_RDY_DIO1; - if (enable) - msc |= ADIS16203_MSC_CTRL_DATA_RDY_EN; - else - msc &= ~ADIS16203_MSC_CTRL_DATA_RDY_EN; - - ret = adis16203_spi_write_reg_16(indio_dev, ADIS16203_MSC_CTRL, msc); - -error_ret: - return ret; -} - -static int adis16203_self_test(struct iio_dev *indio_dev) -{ - int ret; - ret = adis16203_spi_write_reg_16(indio_dev, - ADIS16203_MSC_CTRL, - ADIS16203_MSC_CTRL_SELF_TEST_EN); - if (ret) { - dev_err(&indio_dev->dev, "problem starting self test"); - goto err_ret; - } - - adis16203_check_status(indio_dev); - -err_ret: - return ret; -} - -static int adis16203_initial_setup(struct iio_dev *indio_dev) -{ - int ret; - - /* Disable IRQ */ - ret = adis16203_set_irq(indio_dev, false); - if (ret) { - dev_err(&indio_dev->dev, "disable irq failed"); - goto err_ret; - } - - /* Do self test */ - ret = adis16203_self_test(indio_dev); - if (ret) { - dev_err(&indio_dev->dev, "self test failure"); - goto err_ret; - } - - /* Read status register to check the result */ - ret = adis16203_check_status(indio_dev); - if (ret) { - adis16203_reset(indio_dev); - dev_err(&indio_dev->dev, "device not playing ball -> reset"); - msleep(ADIS16203_STARTUP_DELAY); - ret = adis16203_check_status(indio_dev); - if (ret) { - dev_err(&indio_dev->dev, "giving up"); - goto err_ret; - } - } - -err_ret: - return ret; -} - -enum adis16203_chan { - in_supply, - in_aux, - incli_x, - incli_y, - temp, -}; - -static u8 adis16203_addresses[5][2] = { - [in_supply] = { ADIS16203_SUPPLY_OUT }, - [in_aux] = { ADIS16203_AUX_ADC }, - [incli_x] = { ADIS16203_XINCL_OUT, ADIS16203_INCL_NULL}, - [incli_y] = { ADIS16203_YINCL_OUT }, - [temp] = { ADIS16203_TEMP_OUT } +static const u8 adis16203_addresses[] = { + [ADIS16203_SCAN_INCLI_X] = ADIS16203_INCL_NULL, }; static int adis16203_write_raw(struct iio_dev *indio_dev, @@ -274,9 +34,10 @@ static int adis16203_write_raw(struct iio_dev *indio_dev, int val2, long mask) { + struct adis *st = iio_priv(indio_dev); /* currently only one writable parameter which keeps this simple */ - u8 addr = adis16203_addresses[chan->address][1]; - return adis16203_spi_write_reg_16(indio_dev, addr, val & 0x3FFF); + u8 addr = adis16203_addresses[chan->scan_index]; + return adis_write_reg_16(st, addr, val & 0x3FFF); } static int adis16203_read_raw(struct iio_dev *indio_dev, @@ -284,35 +45,15 @@ static int adis16203_read_raw(struct iio_dev *indio_dev, int *val, int *val2, long mask) { + struct adis *st = iio_priv(indio_dev); int ret; int bits; u8 addr; s16 val16; switch (mask) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); - addr = adis16203_addresses[chan->address][0]; - ret = adis16203_spi_read_reg_16(indio_dev, addr, &val16); - if (ret) { - mutex_unlock(&indio_dev->mlock); - return ret; - } - - if (val16 & ADIS16203_ERROR_ACTIVE) { - ret = adis16203_check_status(indio_dev); - if (ret) { - mutex_unlock(&indio_dev->mlock); - return ret; - } - } - val16 = val16 & ((1 << chan->scan_type.realbits) - 1); - if (chan->scan_type.sign == 's') - val16 = (s16)(val16 << - (16 - chan->scan_type.realbits)) >> - (16 - chan->scan_type.realbits); - *val = val16; - mutex_unlock(&indio_dev->mlock); - return IIO_VAL_INT; + return adis_single_conversion(indio_dev, chan, + ADIS16203_ERROR_ACTIVE, val); case IIO_CHAN_INFO_SCALE: switch (chan->type) { case IIO_VOLTAGE: @@ -341,8 +82,8 @@ static int adis16203_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_CALIBBIAS: bits = 14; mutex_lock(&indio_dev->mlock); - addr = adis16203_addresses[chan->address][1]; - ret = adis16203_spi_read_reg_16(indio_dev, addr, &val16); + addr = adis16203_addresses[chan->scan_index]; + ret = adis_read_reg_16(st, addr, &val16); if (ret) { mutex_unlock(&indio_dev->mlock); return ret; @@ -358,89 +99,53 @@ static int adis16203_read_raw(struct iio_dev *indio_dev, } static const struct iio_chan_spec adis16203_channels[] = { - { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 0, - .extend_name = "supply", - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - .address = in_supply, - .scan_index = ADIS16203_SCAN_SUPPLY, - .scan_type = { - .sign = 'u', - .realbits = 12, - .storagebits = 16, - }, - }, { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - .address = in_aux, - .scan_index = ADIS16203_SCAN_AUX_ADC, - .scan_type = { - .sign = 'u', - .realbits = 12, - .storagebits = 16, - }, - }, { - .type = IIO_INCLI, - .modified = 1, - .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - .address = incli_x, - .scan_index = ADIS16203_SCAN_INCLI_X, - .scan_type = { - .sign = 's', - .realbits = 14, - .storagebits = 16, - }, - }, { /* Fixme: Not what it appears to be - see data sheet */ - .type = IIO_INCLI, - .modified = 1, - .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, - .address = incli_y, - .scan_index = ADIS16203_SCAN_INCLI_Y, - .scan_type = { - .sign = 's', - .realbits = 14, - .storagebits = 16, - }, - }, { - .type = IIO_TEMP, - .indexed = 1, - .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, - .address = temp, - .scan_index = ADIS16203_SCAN_TEMP, - .scan_type = { - .sign = 'u', - .realbits = 12, - .storagebits = 16, - }, - }, + ADIS_SUPPLY_CHAN(ADIS16203_SUPPLY_OUT, ADIS16203_SCAN_SUPPLY, 12), + ADIS_AUX_ADC_CHAN(ADIS16203_AUX_ADC, ADIS16203_SCAN_AUX_ADC, 12), + ADIS_INCLI_CHAN(X, ADIS16203_XINCL_OUT, ADIS16203_SCAN_INCLI_X, + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, 14), + /* Fixme: Not what it appears to be - see data sheet */ + ADIS_INCLI_CHAN(Y, ADIS16203_YINCL_OUT, ADIS16203_SCAN_INCLI_Y, 0, 14), + ADIS_TEMP_CHAN(ADIS16203_TEMP_OUT, ADIS16203_SCAN_TEMP, 12), IIO_CHAN_SOFT_TIMESTAMP(5), }; static const struct iio_info adis16203_info = { .read_raw = &adis16203_read_raw, .write_raw = &adis16203_write_raw, + .update_scan_mode = adis_update_scan_mode, .driver_module = THIS_MODULE, }; -static int __devinit adis16203_probe(struct spi_device *spi) +static const char * const adis16203_status_error_msgs[] = { + [ADIS16203_DIAG_STAT_SELFTEST_FAIL_BIT] = "Self test failure", + [ADIS16203_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure", + [ADIS16203_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed", + [ADIS16203_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V", + [ADIS16203_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 3.15V", +}; + +static const struct adis_data adis16203_data = { + .read_delay = 20, + .msc_ctrl_reg = ADIS16203_MSC_CTRL, + .glob_cmd_reg = ADIS16203_GLOB_CMD, + .diag_stat_reg = ADIS16203_DIAG_STAT, + + .self_test_mask = ADIS16203_MSC_CTRL_SELF_TEST_EN, + .startup_delay = ADIS16203_STARTUP_DELAY, + + .status_error_msgs = adis16203_status_error_msgs, + .status_error_mask = BIT(ADIS16203_DIAG_STAT_SELFTEST_FAIL_BIT) | + BIT(ADIS16203_DIAG_STAT_SPI_FAIL_BIT) | + BIT(ADIS16203_DIAG_STAT_FLASH_UPT_BIT) | + BIT(ADIS16203_DIAG_STAT_POWER_HIGH_BIT) | + BIT(ADIS16203_DIAG_STAT_POWER_LOW_BIT), +}; + +static int adis16203_probe(struct spi_device *spi) { int ret; struct iio_dev *indio_dev; - struct adis16203_state *st; + struct adis *st; /* setup the industrialio driver allocated elements */ indio_dev = iio_device_alloc(sizeof(*st)); @@ -451,8 +156,6 @@ static int __devinit adis16203_probe(struct spi_device *spi) st = iio_priv(indio_dev); /* this is only used for removal purposes */ spi_set_drvdata(spi, indio_dev); - st->us = spi; - mutex_init(&st->buf_lock); indio_dev->name = spi->dev.driver->name; indio_dev->dev.parent = &spi->dev; @@ -461,55 +164,40 @@ static int __devinit adis16203_probe(struct spi_device *spi) indio_dev->info = &adis16203_info; indio_dev->modes = INDIO_DIRECT_MODE; - ret = adis16203_configure_ring(indio_dev); + ret = adis_init(st, indio_dev, spi, &adis16203_data); if (ret) goto error_free_dev; - ret = iio_buffer_register(indio_dev, - adis16203_channels, - ARRAY_SIZE(adis16203_channels)); - if (ret) { - printk(KERN_ERR "failed to initialize the ring\n"); - goto error_unreg_ring_funcs; - } - - if (spi->irq) { - ret = adis16203_probe_trigger(indio_dev); - if (ret) - goto error_uninitialize_ring; - } + ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL); + if (ret) + goto error_free_dev; /* Get the device into a sane initial state */ - ret = adis16203_initial_setup(indio_dev); + ret = adis_initial_startup(st); if (ret) - goto error_remove_trigger; + goto error_cleanup_buffer_trigger; ret = iio_device_register(indio_dev); if (ret) - goto error_remove_trigger; + goto error_cleanup_buffer_trigger; return 0; -error_remove_trigger: - adis16203_remove_trigger(indio_dev); -error_uninitialize_ring: - iio_buffer_unregister(indio_dev); -error_unreg_ring_funcs: - adis16203_unconfigure_ring(indio_dev); +error_cleanup_buffer_trigger: + adis_cleanup_buffer_and_trigger(st, indio_dev); error_free_dev: iio_device_free(indio_dev); error_ret: return ret; } -static int __devexit adis16203_remove(struct spi_device *spi) +static int adis16203_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct adis *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); - adis16203_remove_trigger(indio_dev); - iio_buffer_unregister(indio_dev); - adis16203_unconfigure_ring(indio_dev); + adis_cleanup_buffer_and_trigger(st, indio_dev); iio_device_free(indio_dev); return 0; @@ -521,7 +209,7 @@ static struct spi_driver adis16203_driver = { .owner = THIS_MODULE, }, .probe = adis16203_probe, - .remove = __devexit_p(adis16203_remove), + .remove = adis16203_remove, }; module_spi_driver(adis16203_driver); diff --git a/drivers/staging/iio/accel/adis16203_ring.c b/drivers/staging/iio/accel/adis16203_ring.c deleted file mode 100644 index 7507e1a04591..000000000000 --- a/drivers/staging/iio/accel/adis16203_ring.c +++ /dev/null @@ -1,136 +0,0 @@ -#include <linux/export.h> -#include <linux/interrupt.h> -#include <linux/mutex.h> -#include <linux/kernel.h> -#include <linux/spi/spi.h> -#include <linux/slab.h> - -#include <linux/iio/iio.h> -#include "../ring_sw.h" -#include <linux/iio/trigger_consumer.h> -#include "adis16203.h" - -/** - * adis16203_read_ring_data() read data registers which will be placed into ring - * @indio_dev: the IIO device - * @rx: somewhere to pass back the value read - **/ -static int adis16203_read_ring_data(struct iio_dev *indio_dev, u8 *rx) -{ - struct spi_message msg; - struct adis16203_state *st = iio_priv(indio_dev); - struct spi_transfer xfers[ADIS16203_OUTPUTS + 1]; - int ret; - int i; - - mutex_lock(&st->buf_lock); - - spi_message_init(&msg); - - memset(xfers, 0, sizeof(xfers)); - for (i = 0; i <= ADIS16203_OUTPUTS; i++) { - xfers[i].bits_per_word = 8; - xfers[i].cs_change = 1; - xfers[i].len = 2; - xfers[i].delay_usecs = 20; - xfers[i].tx_buf = st->tx + 2 * i; - if (i < 1) /* SUPPLY_OUT: 0x02, AUX_ADC: 0x08 */ - st->tx[2 * i] = ADIS16203_READ_REG(ADIS16203_SUPPLY_OUT + 2 * i); - else - st->tx[2 * i] = ADIS16203_READ_REG(ADIS16203_SUPPLY_OUT + 2 * i + 6); - st->tx[2 * i + 1] = 0; - if (i >= 1) - xfers[i].rx_buf = rx + 2 * (i - 1); - spi_message_add_tail(&xfers[i], &msg); - } - - ret = spi_sync(st->us, &msg); - if (ret) - dev_err(&st->us->dev, "problem when burst reading"); - - mutex_unlock(&st->buf_lock); - - return ret; -} - -/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device - * specific to be rolled into the core. - */ -static irqreturn_t adis16203_trigger_handler(int irq, void *p) -{ - struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->indio_dev; - struct adis16203_state *st = iio_priv(indio_dev); - - int i = 0; - s16 *data; - - data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); - if (data == NULL) { - dev_err(&st->us->dev, "memory alloc failed in ring bh"); - goto done; - } - - if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) && - adis16203_read_ring_data(indio_dev, st->rx) >= 0) - for (; i < bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength); i++) - data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2])); - - /* Guaranteed to be aligned with 8 byte boundary */ - if (indio_dev->scan_timestamp) - *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - - iio_push_to_buffer(indio_dev->buffer, (u8 *)data); - - kfree(data); -done: - iio_trigger_notify_done(indio_dev->trig); - - return IRQ_HANDLED; -} - -void adis16203_unconfigure_ring(struct iio_dev *indio_dev) -{ - iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_sw_rb_free(indio_dev->buffer); -} - -static const struct iio_buffer_setup_ops adis16203_ring_setup_ops = { - .preenable = &iio_sw_buffer_preenable, - .postenable = &iio_triggered_buffer_postenable, - .predisable = &iio_triggered_buffer_predisable, -}; - -int adis16203_configure_ring(struct iio_dev *indio_dev) -{ - int ret = 0; - struct iio_buffer *ring; - - ring = iio_sw_rb_allocate(indio_dev); - if (!ring) { - ret = -ENOMEM; - return ret; - } - indio_dev->buffer = ring; - ring->scan_timestamp = true; - indio_dev->setup_ops = &adis16203_ring_setup_ops; - - indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, - &adis16203_trigger_handler, - IRQF_ONESHOT, - indio_dev, - "adis16203_consumer%d", - indio_dev->id); - if (indio_dev->pollfunc == NULL) { - ret = -ENOMEM; - goto error_iio_sw_rb_free; - } - - indio_dev->modes |= INDIO_BUFFER_TRIGGERED; - return 0; - -error_iio_sw_rb_free: - iio_sw_rb_free(indio_dev->buffer); - return ret; -} diff --git a/drivers/staging/iio/accel/adis16203_trigger.c b/drivers/staging/iio/accel/adis16203_trigger.c deleted file mode 100644 index b8a04073d6d7..000000000000 --- a/drivers/staging/iio/accel/adis16203_trigger.c +++ /dev/null @@ -1,73 +0,0 @@ -#include <linux/interrupt.h> -#include <linux/kernel.h> -#include <linux/spi/spi.h> -#include <linux/export.h> - -#include <linux/iio/iio.h> -#include <linux/iio/trigger.h> -#include "adis16203.h" - -/** - * adis16203_data_rdy_trigger_set_state() set datardy interrupt state - **/ -static int adis16203_data_rdy_trigger_set_state(struct iio_trigger *trig, - bool state) -{ - struct iio_dev *indio_dev = trig->private_data; - - dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); - return adis16203_set_irq(indio_dev, state); -} - -static const struct iio_trigger_ops adis16203_trigger_ops = { - .owner = THIS_MODULE, - .set_trigger_state = &adis16203_data_rdy_trigger_set_state, -}; - -int adis16203_probe_trigger(struct iio_dev *indio_dev) -{ - int ret; - struct adis16203_state *st = iio_priv(indio_dev); - - st->trig = iio_trigger_alloc("adis16203-dev%d", indio_dev->id); - if (st->trig == NULL) { - ret = -ENOMEM; - goto error_ret; - } - - ret = request_irq(st->us->irq, - &iio_trigger_generic_data_rdy_poll, - IRQF_TRIGGER_RISING, - "adis16203", - st->trig); - if (ret) - goto error_free_trig; - - st->trig->dev.parent = &st->us->dev; - st->trig->ops = &adis16203_trigger_ops; - st->trig->private_data = indio_dev; - ret = iio_trigger_register(st->trig); - - /* select default trigger */ - indio_dev->trig = st->trig; - if (ret) - goto error_free_irq; - - return 0; - -error_free_irq: - free_irq(st->us->irq, st->trig); -error_free_trig: - iio_trigger_free(st->trig); -error_ret: - return ret; -} - -void adis16203_remove_trigger(struct iio_dev *indio_dev) -{ - struct adis16203_state *st = iio_priv(indio_dev); - - iio_trigger_unregister(st->trig); - free_irq(st->us->irq, st->trig); - iio_trigger_free(st->trig); -} diff --git a/drivers/staging/iio/accel/adis16204.h b/drivers/staging/iio/accel/adis16204.h index 7cf4e91f83ad..9ff950c1e8db 100644 --- a/drivers/staging/iio/accel/adis16204.h +++ b/drivers/staging/iio/accel/adis16204.h @@ -3,9 +3,6 @@ #define ADIS16204_STARTUP_DELAY 220 /* ms */ -#define ADIS16204_READ_REG(a) a -#define ADIS16204_WRITE_REG(a) ((a) | 0x80) - #define ADIS16204_FLASH_CNT 0x00 /* Flash memory write count */ #define ADIS16204_SUPPLY_OUT 0x02 /* Output, power supply */ #define ADIS16204_XACCL_OUT 0x04 /* Output, x-axis accelerometer */ @@ -35,8 +32,6 @@ #define ADIS16204_DIAG_STAT 0x3C /* Diagnostics, system status register */ #define ADIS16204_GLOB_CMD 0x3E /* Operation, system command register */ -#define ADIS16204_OUTPUTS 5 - /* MSC_CTRL */ #define ADIS16204_MSC_CTRL_PWRUP_SELF_TEST (1 << 10) /* Self-test at power-on: 1 = disabled, 0 = enabled */ #define ADIS16204_MSC_CTRL_SELF_TEST_EN (1 << 8) /* Self-test enable */ @@ -47,87 +42,27 @@ /* DIAG_STAT */ #define ADIS16204_DIAG_STAT_ALARM2 (1<<9) /* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */ #define ADIS16204_DIAG_STAT_ALARM1 (1<<8) /* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */ -#define ADIS16204_DIAG_STAT_SELFTEST_FAIL (1<<5) /* Self-test diagnostic error flag: 1 = error condition, +#define ADIS16204_DIAG_STAT_SELFTEST_FAIL_BIT 5 /* Self-test diagnostic error flag: 1 = error condition, 0 = normal operation */ -#define ADIS16204_DIAG_STAT_SPI_FAIL (1<<3) /* SPI communications failure */ -#define ADIS16204_DIAG_STAT_FLASH_UPT (1<<2) /* Flash update failure */ -#define ADIS16204_DIAG_STAT_POWER_HIGH (1<<1) /* Power supply above 3.625 V */ -#define ADIS16204_DIAG_STAT_POWER_LOW (1<<0) /* Power supply below 2.975 V */ +#define ADIS16204_DIAG_STAT_SPI_FAIL_BIT 3 /* SPI communications failure */ +#define ADIS16204_DIAG_STAT_FLASH_UPT_BIT 2 /* Flash update failure */ +#define ADIS16204_DIAG_STAT_POWER_HIGH_BIT 1 /* Power supply above 3.625 V */ +#define ADIS16204_DIAG_STAT_POWER_LOW_BIT 0 /* Power supply below 2.975 V */ /* GLOB_CMD */ #define ADIS16204_GLOB_CMD_SW_RESET (1<<7) #define ADIS16204_GLOB_CMD_CLEAR_STAT (1<<4) #define ADIS16204_GLOB_CMD_FACTORY_CAL (1<<1) -#define ADIS16204_MAX_TX 24 -#define ADIS16204_MAX_RX 24 - #define ADIS16204_ERROR_ACTIVE (1<<14) -/** - * struct adis16204_state - device instance specific data - * @us: actual spi_device - * @trig: data ready trigger registered with iio - * @tx: transmit buffer - * @rx: receive buffer - * @buf_lock: mutex to protect tx and rx - **/ -struct adis16204_state { - struct spi_device *us; - struct iio_trigger *trig; - struct mutex buf_lock; - u8 tx[ADIS16204_MAX_TX] ____cacheline_aligned; - u8 rx[ADIS16204_MAX_RX]; -}; - -int adis16204_set_irq(struct iio_dev *indio_dev, bool enable); - enum adis16204_scan { - ADIS16204_SCAN_SUPPLY, ADIS16204_SCAN_ACC_X, ADIS16204_SCAN_ACC_Y, + ADIS16204_SCAN_ACC_XY, + ADIS16204_SCAN_SUPPLY, ADIS16204_SCAN_AUX_ADC, ADIS16204_SCAN_TEMP, }; -#ifdef CONFIG_IIO_BUFFER -void adis16204_remove_trigger(struct iio_dev *indio_dev); -int adis16204_probe_trigger(struct iio_dev *indio_dev); - -ssize_t adis16204_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf); - -int adis16204_configure_ring(struct iio_dev *indio_dev); -void adis16204_unconfigure_ring(struct iio_dev *indio_dev); - -#else /* CONFIG_IIO_BUFFER */ - -static inline void adis16204_remove_trigger(struct iio_dev *indio_dev) -{ -} - -static inline int adis16204_probe_trigger(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline ssize_t -adis16204_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return 0; -} - -static int adis16204_configure_ring(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline void adis16204_unconfigure_ring(struct iio_dev *indio_dev) -{ -} - -#endif /* CONFIG_IIO_BUFFER */ #endif /* SPI_ADIS16204_H_ */ diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c index c6234c2f46aa..f3592668e066 100644 --- a/drivers/staging/iio/accel/adis16204_core.c +++ b/drivers/staging/iio/accel/adis16204_core.c @@ -21,261 +21,16 @@ #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> #include <linux/iio/buffer.h> +#include <linux/iio/imu/adis.h> #include "adis16204.h" -#define DRIVER_NAME "adis16204" - -/** - * adis16204_spi_write_reg_8() - write single byte to a register - * @dev: device associated with child of actual device (iio_dev or iio_trig) - * @reg_address: the address of the register to be written - * @val: the value to write - **/ -static int adis16204_spi_write_reg_8(struct iio_dev *indio_dev, - u8 reg_address, - u8 val) -{ - int ret; - struct adis16204_state *st = iio_priv(indio_dev); - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16204_WRITE_REG(reg_address); - st->tx[1] = val; - - ret = spi_write(st->us, st->tx, 2); - mutex_unlock(&st->buf_lock); - - return ret; -} - -/** - * adis16204_spi_write_reg_16() - write 2 bytes to a pair of registers - * @indio_dev: iio device associated with child of actual device - * @reg_address: the address of the lower of the two registers. Second register - * is assumed to have address one greater. - * @val: value to be written - **/ -static int adis16204_spi_write_reg_16(struct iio_dev *indio_dev, - u8 lower_reg_address, - u16 value) -{ - int ret; - struct spi_message msg; - struct adis16204_state *st = iio_priv(indio_dev); - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - }, { - .tx_buf = st->tx + 2, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16204_WRITE_REG(lower_reg_address); - st->tx[1] = value & 0xFF; - st->tx[2] = ADIS16204_WRITE_REG(lower_reg_address + 1); - st->tx[3] = (value >> 8) & 0xFF; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); - mutex_unlock(&st->buf_lock); - - return ret; -} - -/** - * adis16204_spi_read_reg_16() - read 2 bytes from a 16-bit register - * @indio_dev: iio device associated with child of actual device - * @reg_address: the address of the lower of the two registers. Second register - * is assumed to have address one greater. - * @val: somewhere to pass back the value read - **/ -static int adis16204_spi_read_reg_16(struct iio_dev *indio_dev, - u8 lower_reg_address, - u16 *val) -{ - struct spi_message msg; - struct adis16204_state *st = iio_priv(indio_dev); - int ret; - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .delay_usecs = 20, - }, { - .rx_buf = st->rx, - .bits_per_word = 8, - .len = 2, - .delay_usecs = 20, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16204_READ_REG(lower_reg_address); - st->tx[1] = 0; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); - if (ret) { - dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X", - lower_reg_address); - goto error_ret; - } - *val = (st->rx[0] << 8) | st->rx[1]; - -error_ret: - mutex_unlock(&st->buf_lock); - return ret; -} - -static int adis16204_check_status(struct iio_dev *indio_dev) -{ - u16 status; - int ret; - - ret = adis16204_spi_read_reg_16(indio_dev, - ADIS16204_DIAG_STAT, &status); - if (ret < 0) { - dev_err(&indio_dev->dev, "Reading status failed\n"); - goto error_ret; - } - ret = status & 0x1F; - - if (status & ADIS16204_DIAG_STAT_SELFTEST_FAIL) - dev_err(&indio_dev->dev, "Self test failure\n"); - if (status & ADIS16204_DIAG_STAT_SPI_FAIL) - dev_err(&indio_dev->dev, "SPI failure\n"); - if (status & ADIS16204_DIAG_STAT_FLASH_UPT) - dev_err(&indio_dev->dev, "Flash update failed\n"); - if (status & ADIS16204_DIAG_STAT_POWER_HIGH) - dev_err(&indio_dev->dev, "Power supply above 3.625V\n"); - if (status & ADIS16204_DIAG_STAT_POWER_LOW) - dev_err(&indio_dev->dev, "Power supply below 2.975V\n"); - -error_ret: - return ret; -} - -static int adis16204_reset(struct iio_dev *indio_dev) -{ - int ret; - ret = adis16204_spi_write_reg_8(indio_dev, - ADIS16204_GLOB_CMD, - ADIS16204_GLOB_CMD_SW_RESET); - if (ret) - dev_err(&indio_dev->dev, "problem resetting device"); - - return ret; -} - -int adis16204_set_irq(struct iio_dev *indio_dev, bool enable) -{ - int ret = 0; - u16 msc; - - ret = adis16204_spi_read_reg_16(indio_dev, ADIS16204_MSC_CTRL, &msc); - if (ret) - goto error_ret; - - msc |= ADIS16204_MSC_CTRL_ACTIVE_HIGH; - msc &= ~ADIS16204_MSC_CTRL_DATA_RDY_DIO2; - if (enable) - msc |= ADIS16204_MSC_CTRL_DATA_RDY_EN; - else - msc &= ~ADIS16204_MSC_CTRL_DATA_RDY_EN; - - ret = adis16204_spi_write_reg_16(indio_dev, ADIS16204_MSC_CTRL, msc); - -error_ret: - return ret; -} - -static int adis16204_self_test(struct iio_dev *indio_dev) -{ - int ret; - ret = adis16204_spi_write_reg_16(indio_dev, - ADIS16204_MSC_CTRL, - ADIS16204_MSC_CTRL_SELF_TEST_EN); - if (ret) { - dev_err(&indio_dev->dev, "problem starting self test"); - goto err_ret; - } - - adis16204_check_status(indio_dev); - -err_ret: - return ret; -} - -static int adis16204_initial_setup(struct iio_dev *indio_dev) -{ - int ret; - - /* Disable IRQ */ - ret = adis16204_set_irq(indio_dev, false); - if (ret) { - dev_err(&indio_dev->dev, "disable irq failed"); - goto err_ret; - } - - /* Do self test */ - ret = adis16204_self_test(indio_dev); - if (ret) { - dev_err(&indio_dev->dev, "self test failure"); - goto err_ret; - } - - /* Read status register to check the result */ - ret = adis16204_check_status(indio_dev); - if (ret) { - adis16204_reset(indio_dev); - dev_err(&indio_dev->dev, "device not playing ball -> reset"); - msleep(ADIS16204_STARTUP_DELAY); - ret = adis16204_check_status(indio_dev); - if (ret) { - dev_err(&indio_dev->dev, "giving up"); - goto err_ret; - } - } - -err_ret: - return ret; -} - /* Unique to this driver currently */ -enum adis16204_channel { - in_supply, - in_aux, - temp, - accel_x, - accel_y, - accel_xy, -}; - -static u8 adis16204_addresses[6][3] = { - [in_supply] = { ADIS16204_SUPPLY_OUT }, - [in_aux] = { ADIS16204_AUX_ADC }, - [temp] = { ADIS16204_TEMP_OUT }, - [accel_x] = { ADIS16204_XACCL_OUT, ADIS16204_XACCL_NULL, - ADIS16204_X_PEAK_OUT }, - [accel_y] = { ADIS16204_XACCL_OUT, ADIS16204_YACCL_NULL, - ADIS16204_Y_PEAK_OUT }, - [accel_xy] = { ADIS16204_XY_RSS_OUT, 0, - ADIS16204_XY_PEAK_OUT }, +static const u8 adis16204_addresses[][2] = { + [ADIS16204_SCAN_ACC_X] = { ADIS16204_XACCL_NULL, ADIS16204_X_PEAK_OUT }, + [ADIS16204_SCAN_ACC_Y] = { ADIS16204_YACCL_NULL, ADIS16204_Y_PEAK_OUT }, + [ADIS16204_SCAN_ACC_XY] = { 0, ADIS16204_XY_PEAK_OUT }, }; static int adis16204_read_raw(struct iio_dev *indio_dev, @@ -283,6 +38,7 @@ static int adis16204_read_raw(struct iio_dev *indio_dev, int *val, int *val2, long mask) { + struct adis *st = iio_priv(indio_dev); int ret; int bits; u8 addr; @@ -291,29 +47,8 @@ static int adis16204_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); - addr = adis16204_addresses[chan->address][0]; - ret = adis16204_spi_read_reg_16(indio_dev, addr, &val16); - if (ret) { - mutex_unlock(&indio_dev->mlock); - return ret; - } - - if (val16 & ADIS16204_ERROR_ACTIVE) { - ret = adis16204_check_status(indio_dev); - if (ret) { - mutex_unlock(&indio_dev->mlock); - return ret; - } - } - val16 = val16 & ((1 << chan->scan_type.realbits) - 1); - if (chan->scan_type.sign == 's') - val16 = (s16)(val16 << - (16 - chan->scan_type.realbits)) >> - (16 - chan->scan_type.realbits); - *val = val16; - mutex_unlock(&indio_dev->mlock); - return IIO_VAL_INT; + return adis_single_conversion(indio_dev, chan, + ADIS16204_ERROR_ACTIVE, val); case IIO_CHAN_INFO_SCALE: switch (chan->type) { case IIO_VOLTAGE: @@ -353,14 +88,14 @@ static int adis16204_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_PEAK: if (mask == IIO_CHAN_INFO_CALIBBIAS) { bits = 12; - addrind = 1; + addrind = 0; } else { /* PEAK_SEPARATE */ bits = 14; - addrind = 2; + addrind = 1; } mutex_lock(&indio_dev->mlock); - addr = adis16204_addresses[chan->address][addrind]; - ret = adis16204_spi_read_reg_16(indio_dev, addr, &val16); + addr = adis16204_addresses[chan->scan_index][addrind]; + ret = adis_read_reg_16(st, addr, &val16); if (ret) { mutex_unlock(&indio_dev->mlock); return ret; @@ -380,6 +115,7 @@ static int adis16204_write_raw(struct iio_dev *indio_dev, int val2, long mask) { + struct adis *st = iio_priv(indio_dev); int bits; s16 val16; u8 addr; @@ -391,114 +127,65 @@ static int adis16204_write_raw(struct iio_dev *indio_dev, break; default: return -EINVAL; - }; + } val16 = val & ((1 << bits) - 1); - addr = adis16204_addresses[chan->address][1]; - return adis16204_spi_write_reg_16(indio_dev, addr, val16); + addr = adis16204_addresses[chan->scan_index][1]; + return adis_write_reg_16(st, addr, val16); } return -EINVAL; } static const struct iio_chan_spec adis16204_channels[] = { - { - .type = IIO_VOLTAGE, - .indexed = 1, /* Note was not previously indexed */ - .channel = 0, - .extend_name = "supply", - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - .address = in_supply, - .scan_index = ADIS16204_SCAN_SUPPLY, - .scan_type = { - .sign = 'u', - .realbits = 12, - .storagebits = 16, - }, - }, { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - .address = in_aux, - .scan_index = ADIS16204_SCAN_AUX_ADC, - .scan_type = { - .sign = 'u', - .realbits = 12, - .storagebits = 16, - }, - }, { - .type = IIO_TEMP, - .indexed = 1, - .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, - .address = temp, - .scan_index = ADIS16204_SCAN_TEMP, - .scan_type = { - .sign = 'u', - .realbits = 12, - .storagebits = 16, - }, - }, { - .type = IIO_ACCEL, - .modified = 1, - .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | + ADIS_SUPPLY_CHAN(ADIS16204_SUPPLY_OUT, ADIS16204_SCAN_SUPPLY, 12), + ADIS_AUX_ADC_CHAN(ADIS16204_AUX_ADC, ADIS16204_SCAN_AUX_ADC, 12), + ADIS_TEMP_CHAN(ADIS16204_TEMP_OUT, ADIS16204_SCAN_TEMP, 12), + ADIS_ACCEL_CHAN(X, ADIS16204_XACCL_OUT, ADIS16204_SCAN_ACC_X, IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | - IIO_CHAN_INFO_PEAK_SEPARATE_BIT, - .address = accel_x, - .scan_index = ADIS16204_SCAN_ACC_X, - .scan_type = { - .sign = 's', - .realbits = 14, - .storagebits = 16, - }, - }, { - .type = IIO_ACCEL, - .modified = 1, - .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | + IIO_CHAN_INFO_PEAK_SEPARATE_BIT, 14), + ADIS_ACCEL_CHAN(Y, ADIS16204_YACCL_OUT, ADIS16204_SCAN_ACC_Y, IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | - IIO_CHAN_INFO_PEAK_SEPARATE_BIT, - .address = accel_y, - .scan_index = ADIS16204_SCAN_ACC_Y, - .scan_type = { - .sign = 's', - .realbits = 14, - .storagebits = 16, - }, - }, + IIO_CHAN_INFO_PEAK_SEPARATE_BIT, 14), + ADIS_ACCEL_CHAN(ROOT_SUM_SQUARED_X_Y, ADIS16204_XY_RSS_OUT, + ADIS16204_SCAN_ACC_XY, IIO_CHAN_INFO_PEAK_SEPARATE_BIT, 14), IIO_CHAN_SOFT_TIMESTAMP(5), - { - .type = IIO_ACCEL, - .modified = 1, - .channel2 = IIO_MOD_ROOT_SUM_SQUARED_X_Y, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_PEAK_SEPARATE_BIT, - .address = accel_xy, - .scan_type = { - .sign = 'u', - .realbits = 14, - .storagebits = 16, - }, - } }; static const struct iio_info adis16204_info = { .read_raw = &adis16204_read_raw, .write_raw = &adis16204_write_raw, + .update_scan_mode = adis_update_scan_mode, .driver_module = THIS_MODULE, }; -static int __devinit adis16204_probe(struct spi_device *spi) +static const char * const adis16204_status_error_msgs[] = { + [ADIS16204_DIAG_STAT_SELFTEST_FAIL_BIT] = "Self test failure", + [ADIS16204_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure", + [ADIS16204_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed", + [ADIS16204_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V", + [ADIS16204_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 2.975V", +}; + +static const struct adis_data adis16204_data = { + .read_delay = 20, + .msc_ctrl_reg = ADIS16204_MSC_CTRL, + .glob_cmd_reg = ADIS16204_GLOB_CMD, + .diag_stat_reg = ADIS16204_DIAG_STAT, + + .self_test_mask = ADIS16204_MSC_CTRL_SELF_TEST_EN, + .startup_delay = ADIS16204_STARTUP_DELAY, + + .status_error_msgs = adis16204_status_error_msgs, + .status_error_mask = BIT(ADIS16204_DIAG_STAT_SELFTEST_FAIL_BIT) | + BIT(ADIS16204_DIAG_STAT_SPI_FAIL_BIT) | + BIT(ADIS16204_DIAG_STAT_FLASH_UPT_BIT) | + BIT(ADIS16204_DIAG_STAT_POWER_HIGH_BIT) | + BIT(ADIS16204_DIAG_STAT_POWER_LOW_BIT), +}; + +static int adis16204_probe(struct spi_device *spi) { int ret; - struct adis16204_state *st; + struct adis *st; struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ @@ -510,8 +197,6 @@ static int __devinit adis16204_probe(struct spi_device *spi) st = iio_priv(indio_dev); /* this is only used for removal purposes */ spi_set_drvdata(spi, indio_dev); - st->us = spi; - mutex_init(&st->buf_lock); indio_dev->name = spi->dev.driver->name; indio_dev->dev.parent = &spi->dev; @@ -520,54 +205,39 @@ static int __devinit adis16204_probe(struct spi_device *spi) indio_dev->num_channels = ARRAY_SIZE(adis16204_channels); indio_dev->modes = INDIO_DIRECT_MODE; - ret = adis16204_configure_ring(indio_dev); + ret = adis_init(st, indio_dev, spi, &adis16204_data); if (ret) goto error_free_dev; - ret = iio_buffer_register(indio_dev, - adis16204_channels, - 6); - if (ret) { - printk(KERN_ERR "failed to initialize the ring\n"); - goto error_unreg_ring_funcs; - } - - if (spi->irq) { - ret = adis16204_probe_trigger(indio_dev); - if (ret) - goto error_uninitialize_ring; - } + ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL); + if (ret) + goto error_free_dev; /* Get the device into a sane initial state */ - ret = adis16204_initial_setup(indio_dev); + ret = adis_initial_startup(st); if (ret) - goto error_remove_trigger; + goto error_cleanup_buffer_trigger; ret = iio_device_register(indio_dev); if (ret) - goto error_remove_trigger; + goto error_cleanup_buffer_trigger; return 0; -error_remove_trigger: - adis16204_remove_trigger(indio_dev); -error_uninitialize_ring: - iio_buffer_unregister(indio_dev); -error_unreg_ring_funcs: - adis16204_unconfigure_ring(indio_dev); +error_cleanup_buffer_trigger: + adis_cleanup_buffer_and_trigger(st, indio_dev); error_free_dev: iio_device_free(indio_dev); error_ret: return ret; } -static int __devexit adis16204_remove(struct spi_device *spi) +static int adis16204_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct adis *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); - adis16204_remove_trigger(indio_dev); - iio_buffer_unregister(indio_dev); - adis16204_unconfigure_ring(indio_dev); + adis_cleanup_buffer_and_trigger(st, indio_dev); iio_device_free(indio_dev); return 0; @@ -579,7 +249,7 @@ static struct spi_driver adis16204_driver = { .owner = THIS_MODULE, }, .probe = adis16204_probe, - .remove = __devexit_p(adis16204_remove), + .remove = adis16204_remove, }; module_spi_driver(adis16204_driver); diff --git a/drivers/staging/iio/accel/adis16204_ring.c b/drivers/staging/iio/accel/adis16204_ring.c deleted file mode 100644 index 4c976bec986b..000000000000 --- a/drivers/staging/iio/accel/adis16204_ring.c +++ /dev/null @@ -1,134 +0,0 @@ -#include <linux/export.h> -#include <linux/interrupt.h> -#include <linux/mutex.h> -#include <linux/kernel.h> -#include <linux/spi/spi.h> -#include <linux/slab.h> - -#include <linux/iio/iio.h> -#include "../ring_sw.h" -#include <linux/iio/trigger_consumer.h> -#include "adis16204.h" - -/** - * adis16204_read_ring_data() read data registers which will be placed into ring - * @indio_dev: the IIO device - * @rx: somewhere to pass back the value read - **/ -static int adis16204_read_ring_data(struct iio_dev *indio_dev, u8 *rx) -{ - struct spi_message msg; - struct adis16204_state *st = iio_priv(indio_dev); - struct spi_transfer xfers[ADIS16204_OUTPUTS + 1]; - int ret; - int i; - - mutex_lock(&st->buf_lock); - - spi_message_init(&msg); - - memset(xfers, 0, sizeof(xfers)); - for (i = 0; i <= ADIS16204_OUTPUTS; i++) { - xfers[i].bits_per_word = 8; - xfers[i].cs_change = 1; - xfers[i].len = 2; - xfers[i].delay_usecs = 20; - xfers[i].tx_buf = st->tx + 2 * i; - st->tx[2 * i] - = ADIS16204_READ_REG(ADIS16204_SUPPLY_OUT + 2 * i); - st->tx[2 * i + 1] = 0; - if (i >= 1) - xfers[i].rx_buf = rx + 2 * (i - 1); - spi_message_add_tail(&xfers[i], &msg); - } - - ret = spi_sync(st->us, &msg); - if (ret) - dev_err(&st->us->dev, "problem when burst reading"); - - mutex_unlock(&st->buf_lock); - - return ret; -} - -/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device - * specific to be rolled into the core. - */ -static irqreturn_t adis16204_trigger_handler(int irq, void *p) -{ - struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->indio_dev; - struct adis16204_state *st = iio_priv(indio_dev); - int i = 0; - s16 *data; - - data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); - if (data == NULL) { - dev_err(&st->us->dev, "memory alloc failed in ring bh"); - goto done; - } - - if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) && - adis16204_read_ring_data(indio_dev, st->rx) >= 0) - for (; i < bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength); i++) - data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2])); - - /* Guaranteed to be aligned with 8 byte boundary */ - if (indio_dev->scan_timestamp) - *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - - iio_push_to_buffer(indio_dev->buffer, (u8 *)data); - - kfree(data); -done: - iio_trigger_notify_done(indio_dev->trig); - - return IRQ_HANDLED; -} - -void adis16204_unconfigure_ring(struct iio_dev *indio_dev) -{ - iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_sw_rb_free(indio_dev->buffer); -} - -static const struct iio_buffer_setup_ops adis16204_ring_setup_ops = { - .preenable = &iio_sw_buffer_preenable, - .postenable = &iio_triggered_buffer_postenable, - .predisable = &iio_triggered_buffer_predisable, -}; - -int adis16204_configure_ring(struct iio_dev *indio_dev) -{ - int ret = 0; - struct iio_buffer *ring; - - ring = iio_sw_rb_allocate(indio_dev); - if (!ring) { - ret = -ENOMEM; - return ret; - } - indio_dev->buffer = ring; - ring->scan_timestamp = true; - indio_dev->setup_ops = &adis16204_ring_setup_ops; - - indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, - &adis16204_trigger_handler, - IRQF_ONESHOT, - indio_dev, - "%s_consumer%d", - indio_dev->name, - indio_dev->id); - if (indio_dev->pollfunc == NULL) { - ret = -ENOMEM; - goto error_iio_sw_rb_free; - } - - indio_dev->modes |= INDIO_BUFFER_TRIGGERED; - return 0; - -error_iio_sw_rb_free: - iio_sw_rb_free(indio_dev->buffer); - return ret; -} diff --git a/drivers/staging/iio/accel/adis16204_trigger.c b/drivers/staging/iio/accel/adis16204_trigger.c deleted file mode 100644 index 408a1682368e..000000000000 --- a/drivers/staging/iio/accel/adis16204_trigger.c +++ /dev/null @@ -1,73 +0,0 @@ -#include <linux/interrupt.h> -#include <linux/kernel.h> -#include <linux/spi/spi.h> -#include <linux/export.h> - -#include <linux/iio/iio.h> -#include <linux/iio/trigger.h> -#include "adis16204.h" - -/** - * adis16204_data_rdy_trigger_set_state() set datardy interrupt state - **/ -static int adis16204_data_rdy_trigger_set_state(struct iio_trigger *trig, - bool state) -{ - struct iio_dev *indio_dev = trig->private_data; - - dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); - return adis16204_set_irq(indio_dev, state); -} - -static const struct iio_trigger_ops adis16204_trigger_ops = { - .owner = THIS_MODULE, - .set_trigger_state = &adis16204_data_rdy_trigger_set_state, -}; - -int adis16204_probe_trigger(struct iio_dev *indio_dev) -{ - int ret; - struct adis16204_state *st = iio_priv(indio_dev); - - st->trig = iio_trigger_alloc("adis16204-dev%d", indio_dev->id); - if (st->trig == NULL) { - ret = -ENOMEM; - goto error_ret; - } - - ret = request_irq(st->us->irq, - &iio_trigger_generic_data_rdy_poll, - IRQF_TRIGGER_RISING, - "adis16204", - st->trig); - if (ret) - goto error_free_trig; - - st->trig->dev.parent = &st->us->dev; - st->trig->ops = &adis16204_trigger_ops; - st->trig->private_data = indio_dev; - ret = iio_trigger_register(st->trig); - - /* select default trigger */ - indio_dev->trig = st->trig; - if (ret) - goto error_free_irq; - - return 0; - -error_free_irq: - free_irq(st->us->irq, st->trig); -error_free_trig: - iio_trigger_free(st->trig); -error_ret: - return ret; -} - -void adis16204_remove_trigger(struct iio_dev *indio_dev) -{ - struct adis16204_state *state = iio_priv(indio_dev); - - iio_trigger_unregister(state->trig); - free_irq(state->us->irq, state->trig); - iio_trigger_free(state->trig); -} diff --git a/drivers/staging/iio/accel/adis16209.h b/drivers/staging/iio/accel/adis16209.h index 3c88b86e7b81..ad3945a06292 100644 --- a/drivers/staging/iio/accel/adis16209.h +++ b/drivers/staging/iio/accel/adis16209.h @@ -3,9 +3,6 @@ #define ADIS16209_STARTUP_DELAY 220 /* ms */ -#define ADIS16209_READ_REG(a) a -#define ADIS16209_WRITE_REG(a) ((a) | 0x80) - /* Flash memory write count */ #define ADIS16209_FLASH_CNT 0x00 /* Output, power supply */ @@ -61,8 +58,6 @@ /* Operation, system command register */ #define ADIS16209_GLOB_CMD 0x3E -#define ADIS16209_OUTPUTS 8 - /* MSC_CTRL */ /* Self-test at power-on: 1 = disabled, 0 = enabled */ #define ADIS16209_MSC_CTRL_PWRUP_SELF_TEST (1 << 10) @@ -81,44 +76,23 @@ /* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */ #define ADIS16209_DIAG_STAT_ALARM1 (1<<8) /* Self-test diagnostic error flag: 1 = error condition, 0 = normal operation */ -#define ADIS16209_DIAG_STAT_SELFTEST_FAIL (1<<5) +#define ADIS16209_DIAG_STAT_SELFTEST_FAIL_BIT 5 /* SPI communications failure */ -#define ADIS16209_DIAG_STAT_SPI_FAIL (1<<3) +#define ADIS16209_DIAG_STAT_SPI_FAIL_BIT 3 /* Flash update failure */ -#define ADIS16209_DIAG_STAT_FLASH_UPT (1<<2) +#define ADIS16209_DIAG_STAT_FLASH_UPT_BIT 2 /* Power supply above 3.625 V */ -#define ADIS16209_DIAG_STAT_POWER_HIGH (1<<1) +#define ADIS16209_DIAG_STAT_POWER_HIGH_BIT 1 /* Power supply below 3.15 V */ -#define ADIS16209_DIAG_STAT_POWER_LOW (1<<0) +#define ADIS16209_DIAG_STAT_POWER_LOW_BIT 0 /* GLOB_CMD */ #define ADIS16209_GLOB_CMD_SW_RESET (1<<7) #define ADIS16209_GLOB_CMD_CLEAR_STAT (1<<4) #define ADIS16209_GLOB_CMD_FACTORY_CAL (1<<1) -#define ADIS16209_MAX_TX 24 -#define ADIS16209_MAX_RX 24 - #define ADIS16209_ERROR_ACTIVE (1<<14) -/** - * struct adis16209_state - device instance specific data - * @us: actual spi_device - * @trig: data ready trigger registered with iio - * @tx: transmit buffer - * @rx: receive buffer - * @buf_lock: mutex to protect tx and rx - **/ -struct adis16209_state { - struct spi_device *us; - struct iio_trigger *trig; - struct mutex buf_lock; - u8 tx[ADIS16209_MAX_TX] ____cacheline_aligned; - u8 rx[ADIS16209_MAX_RX]; -}; - -int adis16209_set_irq(struct iio_dev *indio_dev, bool enable); - #define ADIS16209_SCAN_SUPPLY 0 #define ADIS16209_SCAN_ACC_X 1 #define ADIS16209_SCAN_ACC_Y 2 @@ -128,45 +102,4 @@ int adis16209_set_irq(struct iio_dev *indio_dev, bool enable); #define ADIS16209_SCAN_INCLI_Y 6 #define ADIS16209_SCAN_ROT 7 -#ifdef CONFIG_IIO_BUFFER - -void adis16209_remove_trigger(struct iio_dev *indio_dev); -int adis16209_probe_trigger(struct iio_dev *indio_dev); - -ssize_t adis16209_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf); - -int adis16209_configure_ring(struct iio_dev *indio_dev); -void adis16209_unconfigure_ring(struct iio_dev *indio_dev); - -#else /* CONFIG_IIO_BUFFER */ - -static inline void adis16209_remove_trigger(struct iio_dev *indio_dev) -{ -} - -static inline int adis16209_probe_trigger(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline ssize_t -adis16209_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return 0; -} - -static int adis16209_configure_ring(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline void adis16209_unconfigure_ring(struct iio_dev *indio_dev) -{ -} - -#endif /* CONFIG_IIO_BUFFER */ #endif /* SPI_ADIS16209_H_ */ diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c index 7ee974b45d7d..69c50ee44ce3 100644 --- a/drivers/staging/iio/accel/adis16209_core.c +++ b/drivers/staging/iio/accel/adis16209_core.c @@ -19,262 +19,19 @@ #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> #include <linux/iio/buffer.h> +#include <linux/iio/imu/adis.h> #include "adis16209.h" -#define DRIVER_NAME "adis16209" - -/** - * adis16209_spi_write_reg_8() - write single byte to a register - * @indio_dev: iio device associated with actual device - * @reg_address: the address of the register to be written - * @val: the value to write - **/ -static int adis16209_spi_write_reg_8(struct iio_dev *indio_dev, - u8 reg_address, - u8 val) -{ - int ret; - struct adis16209_state *st = iio_priv(indio_dev); - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16209_WRITE_REG(reg_address); - st->tx[1] = val; - - ret = spi_write(st->us, st->tx, 2); - mutex_unlock(&st->buf_lock); - - return ret; -} - -/** - * adis16209_spi_write_reg_16() - write 2 bytes to a pair of registers - * @indio_dev: iio device associated actual device - * @reg_address: the address of the lower of the two registers. Second register - * is assumed to have address one greater. - * @val: value to be written - **/ -static int adis16209_spi_write_reg_16(struct iio_dev *indio_dev, - u8 lower_reg_address, - u16 value) -{ - int ret; - struct spi_message msg; - struct adis16209_state *st = iio_priv(indio_dev); - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .delay_usecs = 30, - }, { - .tx_buf = st->tx + 2, - .bits_per_word = 8, - .len = 2, - .delay_usecs = 30, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16209_WRITE_REG(lower_reg_address); - st->tx[1] = value & 0xFF; - st->tx[2] = ADIS16209_WRITE_REG(lower_reg_address + 1); - st->tx[3] = (value >> 8) & 0xFF; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); - mutex_unlock(&st->buf_lock); - - return ret; -} - -/** - * adis16209_spi_read_reg_16() - read 2 bytes from a 16-bit register - * @indio_dev: iio device associated with device - * @reg_address: the address of the lower of the two registers. Second register - * is assumed to have address one greater. - * @val: somewhere to pass back the value read - **/ -static int adis16209_spi_read_reg_16(struct iio_dev *indio_dev, - u8 lower_reg_address, - u16 *val) -{ - struct spi_message msg; - struct adis16209_state *st = iio_priv(indio_dev); - int ret; - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .delay_usecs = 30, - }, { - .rx_buf = st->rx, - .bits_per_word = 8, - .len = 2, - .delay_usecs = 30, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16209_READ_REG(lower_reg_address); - st->tx[1] = 0; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); - if (ret) { - dev_err(&st->us->dev, - "problem when reading 16 bit register 0x%02X", - lower_reg_address); - goto error_ret; - } - *val = (st->rx[0] << 8) | st->rx[1]; - -error_ret: - mutex_unlock(&st->buf_lock); - return ret; -} - -static int adis16209_reset(struct iio_dev *indio_dev) -{ - int ret; - ret = adis16209_spi_write_reg_8(indio_dev, - ADIS16209_GLOB_CMD, - ADIS16209_GLOB_CMD_SW_RESET); - if (ret) - dev_err(&indio_dev->dev, "problem resetting device"); - - return ret; -} - -int adis16209_set_irq(struct iio_dev *indio_dev, bool enable) -{ - int ret = 0; - u16 msc; - - ret = adis16209_spi_read_reg_16(indio_dev, ADIS16209_MSC_CTRL, &msc); - if (ret) - goto error_ret; - - msc |= ADIS16209_MSC_CTRL_ACTIVE_HIGH; - msc &= ~ADIS16209_MSC_CTRL_DATA_RDY_DIO2; - if (enable) - msc |= ADIS16209_MSC_CTRL_DATA_RDY_EN; - else - msc &= ~ADIS16209_MSC_CTRL_DATA_RDY_EN; - - ret = adis16209_spi_write_reg_16(indio_dev, ADIS16209_MSC_CTRL, msc); - -error_ret: - return ret; -} - -static int adis16209_check_status(struct iio_dev *indio_dev) -{ - u16 status; - int ret; - - ret = adis16209_spi_read_reg_16(indio_dev, - ADIS16209_DIAG_STAT, &status); - if (ret < 0) { - dev_err(&indio_dev->dev, "Reading status failed\n"); - goto error_ret; - } - ret = status & 0x1F; - - if (status & ADIS16209_DIAG_STAT_SELFTEST_FAIL) - dev_err(&indio_dev->dev, "Self test failure\n"); - if (status & ADIS16209_DIAG_STAT_SPI_FAIL) - dev_err(&indio_dev->dev, "SPI failure\n"); - if (status & ADIS16209_DIAG_STAT_FLASH_UPT) - dev_err(&indio_dev->dev, "Flash update failed\n"); - if (status & ADIS16209_DIAG_STAT_POWER_HIGH) - dev_err(&indio_dev->dev, "Power supply above 3.625V\n"); - if (status & ADIS16209_DIAG_STAT_POWER_LOW) - dev_err(&indio_dev->dev, "Power supply below 3.15V\n"); - -error_ret: - return ret; -} - -static int adis16209_self_test(struct iio_dev *indio_dev) -{ - int ret; - ret = adis16209_spi_write_reg_16(indio_dev, - ADIS16209_MSC_CTRL, - ADIS16209_MSC_CTRL_SELF_TEST_EN); - if (ret) { - dev_err(&indio_dev->dev, "problem starting self test"); - goto err_ret; - } - - adis16209_check_status(indio_dev); - -err_ret: - return ret; -} - -static int adis16209_initial_setup(struct iio_dev *indio_dev) -{ - int ret; - - /* Disable IRQ */ - ret = adis16209_set_irq(indio_dev, false); - if (ret) { - dev_err(&indio_dev->dev, "disable irq failed"); - goto err_ret; - } - - /* Do self test */ - ret = adis16209_self_test(indio_dev); - if (ret) { - dev_err(&indio_dev->dev, "self test failure"); - goto err_ret; - } - - /* Read status register to check the result */ - ret = adis16209_check_status(indio_dev); - if (ret) { - adis16209_reset(indio_dev); - dev_err(&indio_dev->dev, "device not playing ball -> reset"); - msleep(ADIS16209_STARTUP_DELAY); - ret = adis16209_check_status(indio_dev); - if (ret) { - dev_err(&indio_dev->dev, "giving up"); - goto err_ret; - } - } - -err_ret: - return ret; -} - -enum adis16209_chan { - in_supply, - temp, - accel_x, - accel_y, - incli_x, - incli_y, - in_aux, - rot, -}; - -static const u8 adis16209_addresses[8][2] = { - [in_supply] = { ADIS16209_SUPPLY_OUT }, - [in_aux] = { ADIS16209_AUX_ADC }, - [accel_x] = { ADIS16209_XACCL_OUT, ADIS16209_XACCL_NULL }, - [accel_y] = { ADIS16209_YACCL_OUT, ADIS16209_YACCL_NULL }, - [incli_x] = { ADIS16209_XINCL_OUT, ADIS16209_XINCL_NULL }, - [incli_y] = { ADIS16209_YINCL_OUT, ADIS16209_YINCL_NULL }, - [rot] = { ADIS16209_ROT_OUT }, - [temp] = { ADIS16209_TEMP_OUT }, +static const u8 adis16209_addresses[8][1] = { + [ADIS16209_SCAN_SUPPLY] = { }, + [ADIS16209_SCAN_AUX_ADC] = { }, + [ADIS16209_SCAN_ACC_X] = { ADIS16209_XACCL_NULL }, + [ADIS16209_SCAN_ACC_Y] = { ADIS16209_YACCL_NULL }, + [ADIS16209_SCAN_INCLI_X] = { ADIS16209_XINCL_NULL }, + [ADIS16209_SCAN_INCLI_Y] = { ADIS16209_YINCL_NULL }, + [ADIS16209_SCAN_ROT] = { }, + [ADIS16209_SCAN_TEMP] = { }, }; static int adis16209_write_raw(struct iio_dev *indio_dev, @@ -283,6 +40,7 @@ static int adis16209_write_raw(struct iio_dev *indio_dev, int val2, long mask) { + struct adis *st = iio_priv(indio_dev); int bits; s16 val16; u8 addr; @@ -295,10 +53,10 @@ static int adis16209_write_raw(struct iio_dev *indio_dev, break; default: return -EINVAL; - }; + } val16 = val & ((1 << bits) - 1); - addr = adis16209_addresses[chan->address][1]; - return adis16209_spi_write_reg_16(indio_dev, addr, val16); + addr = adis16209_addresses[chan->scan_index][0]; + return adis_write_reg_16(st, addr, val16); } return -EINVAL; } @@ -308,6 +66,7 @@ static int adis16209_read_raw(struct iio_dev *indio_dev, int *val, int *val2, long mask) { + struct adis *st = iio_priv(indio_dev); int ret; int bits; u8 addr; @@ -315,29 +74,8 @@ static int adis16209_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); - addr = adis16209_addresses[chan->address][0]; - ret = adis16209_spi_read_reg_16(indio_dev, addr, &val16); - if (ret) { - mutex_unlock(&indio_dev->mlock); - return ret; - } - - if (val16 & ADIS16209_ERROR_ACTIVE) { - ret = adis16209_check_status(indio_dev); - if (ret) { - mutex_unlock(&indio_dev->mlock); - return ret; - } - } - val16 = val16 & ((1 << chan->scan_type.realbits) - 1); - if (chan->scan_type.sign == 's') - val16 = (s16)(val16 << - (16 - chan->scan_type.realbits)) >> - (16 - chan->scan_type.realbits); - *val = val16; - mutex_unlock(&indio_dev->mlock); - return IIO_VAL_INT; + return adis_single_conversion(indio_dev, chan, + ADIS16209_ERROR_ACTIVE, val); case IIO_CHAN_INFO_SCALE: switch (chan->type) { case IIO_VOLTAGE: @@ -374,10 +112,10 @@ static int adis16209_read_raw(struct iio_dev *indio_dev, break; default: return -EINVAL; - }; + } mutex_lock(&indio_dev->mlock); - addr = adis16209_addresses[chan->address][1]; - ret = adis16209_spi_read_reg_16(indio_dev, addr, &val16); + addr = adis16209_addresses[chan->scan_index][0]; + ret = adis_read_reg_16(st, addr, &val16); if (ret) { mutex_unlock(&indio_dev->mlock); return ret; @@ -392,128 +130,56 @@ static int adis16209_read_raw(struct iio_dev *indio_dev, } static const struct iio_chan_spec adis16209_channels[] = { - { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 0, - .extend_name = "supply", - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - .address = in_supply, - .scan_index = ADIS16209_SCAN_SUPPLY, - .scan_type = { - .sign = 'u', - .realbits = 14, - .storagebits = 16, - }, - }, { - .type = IIO_TEMP, - .indexed = 0, - .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, - .address = temp, - .scan_index = ADIS16209_SCAN_TEMP, - .scan_type = { - .sign = 'u', - .realbits = 12, - .storagebits = 16, - }, - }, { - .type = IIO_ACCEL, - .modified = 1, - .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - .address = accel_x, - .scan_index = ADIS16209_SCAN_ACC_X, - .scan_type = { - .sign = 's', - .realbits = 14, - .storagebits = 16, - }, - }, { - .type = IIO_ACCEL, - .modified = 1, - .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - .address = accel_y, - .scan_index = ADIS16209_SCAN_ACC_Y, - .scan_type = { - .sign = 's', - .realbits = 14, - .storagebits = 16, - }, - }, { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - .address = in_aux, - .scan_index = ADIS16209_SCAN_AUX_ADC, - .scan_type = { - .sign = 'u', - .realbits = 12, - .storagebits = 16, - }, - }, { - .type = IIO_INCLI, - .modified = 1, - .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, - .address = incli_x, - .scan_index = ADIS16209_SCAN_INCLI_X, - .scan_type = { - .sign = 's', - .realbits = 14, - .storagebits = 16, - }, - }, { - .type = IIO_INCLI, - .modified = 1, - .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, - .address = incli_y, - .scan_index = ADIS16209_SCAN_INCLI_Y, - .scan_type = { - .sign = 's', - .realbits = 14, - .storagebits = 16, - }, - }, { - .type = IIO_ROT, - .modified = 1, - .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - .address = rot, - .scan_index = ADIS16209_SCAN_ROT, - .scan_type = { - .sign = 's', - .realbits = 14, - .storagebits = 16, - }, - }, + ADIS_SUPPLY_CHAN(ADIS16209_SUPPLY_OUT, ADIS16209_SCAN_SUPPLY, 14), + ADIS_TEMP_CHAN(ADIS16209_TEMP_OUT, ADIS16209_SCAN_TEMP, 12), + ADIS_ACCEL_CHAN(X, ADIS16209_XACCL_OUT, ADIS16209_SCAN_ACC_X, + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, 14), + ADIS_ACCEL_CHAN(Y, ADIS16209_YACCL_OUT, ADIS16209_SCAN_ACC_Y, + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, 14), + ADIS_AUX_ADC_CHAN(ADIS16209_AUX_ADC, ADIS16209_SCAN_AUX_ADC, 12), + ADIS_INCLI_CHAN(X, ADIS16209_XINCL_OUT, ADIS16209_SCAN_INCLI_X, 0, 14), + ADIS_INCLI_CHAN(Y, ADIS16209_YINCL_OUT, ADIS16209_SCAN_INCLI_Y, 0, 14), + ADIS_ROT_CHAN(X, ADIS16209_ROT_OUT, ADIS16209_SCAN_ROT, 0, 14), IIO_CHAN_SOFT_TIMESTAMP(8) }; static const struct iio_info adis16209_info = { .read_raw = &adis16209_read_raw, .write_raw = &adis16209_write_raw, + .update_scan_mode = adis_update_scan_mode, .driver_module = THIS_MODULE, }; -static int __devinit adis16209_probe(struct spi_device *spi) +static const char * const adis16209_status_error_msgs[] = { + [ADIS16209_DIAG_STAT_SELFTEST_FAIL_BIT] = "Self test failure", + [ADIS16209_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure", + [ADIS16209_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed", + [ADIS16209_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V", + [ADIS16209_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 3.15V", +}; + +static const struct adis_data adis16209_data = { + .read_delay = 30, + .msc_ctrl_reg = ADIS16209_MSC_CTRL, + .glob_cmd_reg = ADIS16209_GLOB_CMD, + .diag_stat_reg = ADIS16209_DIAG_STAT, + + .self_test_mask = ADIS16209_MSC_CTRL_SELF_TEST_EN, + .startup_delay = ADIS16209_STARTUP_DELAY, + + .status_error_msgs = adis16209_status_error_msgs, + .status_error_mask = BIT(ADIS16209_DIAG_STAT_SELFTEST_FAIL_BIT) | + BIT(ADIS16209_DIAG_STAT_SPI_FAIL_BIT) | + BIT(ADIS16209_DIAG_STAT_FLASH_UPT_BIT) | + BIT(ADIS16209_DIAG_STAT_POWER_HIGH_BIT) | + BIT(ADIS16209_DIAG_STAT_POWER_LOW_BIT), +}; + + +static int adis16209_probe(struct spi_device *spi) { int ret; - struct adis16209_state *st; + struct adis *st; struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ @@ -525,8 +191,6 @@ static int __devinit adis16209_probe(struct spi_device *spi) st = iio_priv(indio_dev); /* this is only used for removal purposes */ spi_set_drvdata(spi, indio_dev); - st->us = spi; - mutex_init(&st->buf_lock); indio_dev->name = spi->dev.driver->name; indio_dev->dev.parent = &spi->dev; @@ -535,54 +199,38 @@ static int __devinit adis16209_probe(struct spi_device *spi) indio_dev->num_channels = ARRAY_SIZE(adis16209_channels); indio_dev->modes = INDIO_DIRECT_MODE; - ret = adis16209_configure_ring(indio_dev); + ret = adis_init(st, indio_dev, spi, &adis16209_data); + if (ret) + goto error_free_dev; + ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL); if (ret) goto error_free_dev; - - ret = iio_buffer_register(indio_dev, - adis16209_channels, - ARRAY_SIZE(adis16209_channels)); - if (ret) { - printk(KERN_ERR "failed to initialize the ring\n"); - goto error_unreg_ring_funcs; - } - - if (spi->irq) { - ret = adis16209_probe_trigger(indio_dev); - if (ret) - goto error_uninitialize_ring; - } /* Get the device into a sane initial state */ - ret = adis16209_initial_setup(indio_dev); + ret = adis_initial_startup(st); if (ret) - goto error_remove_trigger; + goto error_cleanup_buffer_trigger; ret = iio_device_register(indio_dev); if (ret) - goto error_remove_trigger; + goto error_cleanup_buffer_trigger; return 0; -error_remove_trigger: - adis16209_remove_trigger(indio_dev); -error_uninitialize_ring: - iio_buffer_unregister(indio_dev); -error_unreg_ring_funcs: - adis16209_unconfigure_ring(indio_dev); +error_cleanup_buffer_trigger: + adis_cleanup_buffer_and_trigger(st, indio_dev); error_free_dev: iio_device_free(indio_dev); error_ret: return ret; } -static int __devexit adis16209_remove(struct spi_device *spi) +static int adis16209_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct adis *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); - adis16209_remove_trigger(indio_dev); - iio_buffer_unregister(indio_dev); - adis16209_unconfigure_ring(indio_dev); + adis_cleanup_buffer_and_trigger(st, indio_dev); iio_device_free(indio_dev); return 0; @@ -594,7 +242,7 @@ static struct spi_driver adis16209_driver = { .owner = THIS_MODULE, }, .probe = adis16209_probe, - .remove = __devexit_p(adis16209_remove), + .remove = adis16209_remove, }; module_spi_driver(adis16209_driver); diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c deleted file mode 100644 index f939e29d6c82..000000000000 --- a/drivers/staging/iio/accel/adis16209_ring.c +++ /dev/null @@ -1,134 +0,0 @@ -#include <linux/export.h> -#include <linux/interrupt.h> -#include <linux/mutex.h> -#include <linux/kernel.h> -#include <linux/spi/spi.h> -#include <linux/slab.h> - -#include <linux/iio/iio.h> -#include "../ring_sw.h" -#include <linux/iio/trigger_consumer.h> -#include "adis16209.h" - -/** - * adis16209_read_ring_data() read data registers which will be placed into ring - * @indio_dev: the IIO device - * @rx: somewhere to pass back the value read - **/ -static int adis16209_read_ring_data(struct iio_dev *indio_dev, u8 *rx) -{ - struct spi_message msg; - struct adis16209_state *st = iio_priv(indio_dev); - struct spi_transfer xfers[ADIS16209_OUTPUTS + 1]; - int ret; - int i; - - mutex_lock(&st->buf_lock); - - spi_message_init(&msg); - - memset(xfers, 0, sizeof(xfers)); - for (i = 0; i <= ADIS16209_OUTPUTS; i++) { - xfers[i].bits_per_word = 8; - xfers[i].cs_change = 1; - xfers[i].len = 2; - xfers[i].delay_usecs = 30; - xfers[i].tx_buf = st->tx + 2 * i; - st->tx[2 * i] - = ADIS16209_READ_REG(ADIS16209_SUPPLY_OUT + 2 * i); - st->tx[2 * i + 1] = 0; - if (i >= 1) - xfers[i].rx_buf = rx + 2 * (i - 1); - spi_message_add_tail(&xfers[i], &msg); - } - - ret = spi_sync(st->us, &msg); - if (ret) - dev_err(&st->us->dev, "problem when burst reading"); - - mutex_unlock(&st->buf_lock); - - return ret; -} - -/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device - * specific to be rolled into the core. - */ -static irqreturn_t adis16209_trigger_handler(int irq, void *p) -{ - struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->indio_dev; - struct adis16209_state *st = iio_priv(indio_dev); - int i = 0; - s16 *data; - - data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); - if (data == NULL) { - dev_err(&st->us->dev, "memory alloc failed in ring bh"); - goto done; - } - - if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) && - adis16209_read_ring_data(indio_dev, st->rx) >= 0) - for (; i < bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength); i++) - data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2])); - - /* Guaranteed to be aligned with 8 byte boundary */ - if (indio_dev->scan_timestamp) - *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - - iio_push_to_buffer(indio_dev->buffer, (u8 *)data); - - kfree(data); -done: - iio_trigger_notify_done(indio_dev->trig); - - return IRQ_HANDLED; -} - -void adis16209_unconfigure_ring(struct iio_dev *indio_dev) -{ - iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_sw_rb_free(indio_dev->buffer); -} - -static const struct iio_buffer_setup_ops adis16209_ring_setup_ops = { - .preenable = &iio_sw_buffer_preenable, - .postenable = &iio_triggered_buffer_postenable, - .predisable = &iio_triggered_buffer_predisable, -}; - -int adis16209_configure_ring(struct iio_dev *indio_dev) -{ - int ret = 0; - struct iio_buffer *ring; - - ring = iio_sw_rb_allocate(indio_dev); - if (!ring) { - ret = -ENOMEM; - return ret; - } - indio_dev->buffer = ring; - ring->scan_timestamp = true; - indio_dev->setup_ops = &adis16209_ring_setup_ops; - - indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, - &adis16209_trigger_handler, - IRQF_ONESHOT, - indio_dev, - "%s_consumer%d", - indio_dev->name, - indio_dev->id); - if (indio_dev->pollfunc == NULL) { - ret = -ENOMEM; - goto error_iio_sw_rb_free; - } - - indio_dev->modes |= INDIO_BUFFER_TRIGGERED; - return 0; - -error_iio_sw_rb_free: - iio_sw_rb_free(indio_dev->buffer); - return ret; -} diff --git a/drivers/staging/iio/accel/adis16209_trigger.c b/drivers/staging/iio/accel/adis16209_trigger.c deleted file mode 100644 index 2ad93dcaf40d..000000000000 --- a/drivers/staging/iio/accel/adis16209_trigger.c +++ /dev/null @@ -1,81 +0,0 @@ -#include <linux/interrupt.h> -#include <linux/kernel.h> -#include <linux/spi/spi.h> -#include <linux/export.h> - -#include <linux/iio/iio.h> -#include <linux/iio/trigger.h> -#include "adis16209.h" - -/** - * adis16209_data_rdy_trig_poll() the event handler for the data rdy trig - **/ -static irqreturn_t adis16209_data_rdy_trig_poll(int irq, void *trig) -{ - iio_trigger_poll(trig, iio_get_time_ns()); - return IRQ_HANDLED; -} - -/** - * adis16209_data_rdy_trigger_set_state() set datardy interrupt state - **/ -static int adis16209_data_rdy_trigger_set_state(struct iio_trigger *trig, - bool state) -{ - struct iio_dev *indio_dev = trig->private_data; - - dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); - return adis16209_set_irq(indio_dev, state); -} - -static const struct iio_trigger_ops adis16209_trigger_ops = { - .owner = THIS_MODULE, - .set_trigger_state = &adis16209_data_rdy_trigger_set_state, -}; - -int adis16209_probe_trigger(struct iio_dev *indio_dev) -{ - int ret; - struct adis16209_state *st = iio_priv(indio_dev); - - st->trig = iio_trigger_alloc("adis16209-dev%d", indio_dev->id); - if (st->trig == NULL) { - ret = -ENOMEM; - goto error_ret; - } - - ret = request_irq(st->us->irq, - adis16209_data_rdy_trig_poll, - IRQF_TRIGGER_RISING, - "adis16209", - st->trig); - if (ret) - goto error_free_trig; - st->trig->dev.parent = &st->us->dev; - st->trig->ops = &adis16209_trigger_ops; - st->trig->private_data = indio_dev; - ret = iio_trigger_register(st->trig); - - /* select default trigger */ - indio_dev->trig = st->trig; - if (ret) - goto error_free_irq; - - return 0; - -error_free_irq: - free_irq(st->us->irq, st->trig); -error_free_trig: - iio_trigger_free(st->trig); -error_ret: - return ret; -} - -void adis16209_remove_trigger(struct iio_dev *indio_dev) -{ - struct adis16209_state *st = iio_priv(indio_dev); - - iio_trigger_unregister(st->trig); - free_irq(st->us->irq, st->trig); - iio_trigger_free(st->trig); -} diff --git a/drivers/staging/iio/accel/adis16220.h b/drivers/staging/iio/accel/adis16220.h index 024313cf5cf0..a894ad7fb26d 100644 --- a/drivers/staging/iio/accel/adis16220.h +++ b/drivers/staging/iio/accel/adis16220.h @@ -1,10 +1,9 @@ #ifndef SPI_ADIS16220_H_ #define SPI_ADIS16220_H_ -#define ADIS16220_STARTUP_DELAY 220 /* ms */ +#include <linux/iio/imu/adis.h> -#define ADIS16220_READ_REG(a) a -#define ADIS16220_WRITE_REG(a) ((a) | 0x80) +#define ADIS16220_STARTUP_DELAY 220 /* ms */ /* Flash memory write count */ #define ADIS16220_FLASH_CNT 0x00 @@ -102,15 +101,15 @@ #define ADIS16220_DIAG_STAT_FLASH_CHK (1<<6) #define ADIS16220_DIAG_STAT_SELF_TEST (1<<5) /* Capture period violation/interruption */ -#define ADIS16220_DIAG_STAT_VIOLATION (1<<4) +#define ADIS16220_DIAG_STAT_VIOLATION_BIT 4 /* SPI communications failure */ -#define ADIS16220_DIAG_STAT_SPI_FAIL (1<<3) +#define ADIS16220_DIAG_STAT_SPI_FAIL_BIT 3 /* Flash update failure */ -#define ADIS16220_DIAG_STAT_FLASH_UPT (1<<2) +#define ADIS16220_DIAG_STAT_FLASH_UPT_BIT 2 /* Power supply above 3.625 V */ -#define ADIS16220_DIAG_STAT_POWER_HIGH (1<<1) +#define ADIS16220_DIAG_STAT_POWER_HIGH_BIT 1 /* Power supply below 3.15 V */ -#define ADIS16220_DIAG_STAT_POWER_LOW (1<<0) +#define ADIS16220_DIAG_STAT_POWER_LOW_BIT 0 /* GLOB_CMD */ #define ADIS16220_GLOB_CMD_SW_RESET (1<<7) @@ -125,13 +124,14 @@ /** * struct adis16220_state - device instance specific data - * @us: actual spi_device + * @adis: adis device * @tx: transmit buffer * @rx: receive buffer * @buf_lock: mutex to protect tx and rx **/ struct adis16220_state { - struct spi_device *us; + struct adis adis; + struct mutex buf_lock; u8 tx[ADIS16220_MAX_TX] ____cacheline_aligned; u8 rx[ADIS16220_MAX_RX]; diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c index eaadd9df3f78..370b01aa767a 100644 --- a/drivers/staging/iio/accel/adis16220_core.c +++ b/drivers/staging/iio/accel/adis16220_core.c @@ -20,138 +20,19 @@ #include "adis16220.h" -#define DRIVER_NAME "adis16220" - -/** - * adis16220_spi_write_reg_8() - write single byte to a register - * @indio_dev: iio device associated with child of actual device - * @reg_address: the address of the register to be written - * @val: the value to write - **/ -static int adis16220_spi_write_reg_8(struct iio_dev *indio_dev, - u8 reg_address, - u8 val) -{ - int ret; - struct adis16220_state *st = iio_priv(indio_dev); - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16220_WRITE_REG(reg_address); - st->tx[1] = val; - - ret = spi_write(st->us, st->tx, 2); - mutex_unlock(&st->buf_lock); - - return ret; -} - -/** - * adis16220_spi_write_reg_16() - write 2 bytes to a pair of registers - * @indio_dev: iio device associated with child of actual device - * @reg_address: the address of the lower of the two registers. Second register - * is assumed to have address one greater. - * @val: value to be written - **/ -static int adis16220_spi_write_reg_16(struct iio_dev *indio_dev, - u8 lower_reg_address, - u16 value) -{ - int ret; - struct spi_message msg; - struct adis16220_state *st = iio_priv(indio_dev); - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .delay_usecs = 35, - }, { - .tx_buf = st->tx + 2, - .bits_per_word = 8, - .len = 2, - .delay_usecs = 35, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16220_WRITE_REG(lower_reg_address); - st->tx[1] = value & 0xFF; - st->tx[2] = ADIS16220_WRITE_REG(lower_reg_address + 1); - st->tx[3] = (value >> 8) & 0xFF; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); - mutex_unlock(&st->buf_lock); - - return ret; -} - -/** - * adis16220_spi_read_reg_16() - read 2 bytes from a 16-bit register - * @indio_dev: iio device associated with child of actual device - * @reg_address: the address of the lower of the two registers. Second register - * is assumed to have address one greater. - * @val: somewhere to pass back the value read - **/ -static int adis16220_spi_read_reg_16(struct iio_dev *indio_dev, - u8 lower_reg_address, - u16 *val) -{ - struct spi_message msg; - struct adis16220_state *st = iio_priv(indio_dev); - int ret; - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .delay_usecs = 35, - }, { - .rx_buf = st->rx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .delay_usecs = 35, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16220_READ_REG(lower_reg_address); - st->tx[1] = 0; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); - if (ret) { - dev_err(&st->us->dev, - "problem when reading 16 bit register 0x%02X", - lower_reg_address); - goto error_ret; - } - *val = (st->rx[0] << 8) | st->rx[1]; - -error_ret: - mutex_unlock(&st->buf_lock); - return ret; -} - static ssize_t adis16220_read_16bit(struct device *dev, struct device_attribute *attr, char *buf) { struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct adis16220_state *st = iio_priv(indio_dev); ssize_t ret; s16 val = 0; /* Take the iio_dev status lock */ mutex_lock(&indio_dev->mlock); - ret = adis16220_spi_read_reg_16(indio_dev, this_attr->address, + ret = adis_read_reg_16(&st->adis, this_attr->address, (u16 *)&val); mutex_unlock(&indio_dev->mlock); if (ret) @@ -166,13 +47,14 @@ static ssize_t adis16220_write_16bit(struct device *dev, { struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + struct adis16220_state *st = iio_priv(indio_dev); int ret; u16 val; ret = kstrtou16(buf, 10, &val); if (ret) goto error_ret; - ret = adis16220_spi_write_reg_16(indio_dev, this_attr->address, val); + ret = adis_write_reg_16(&st->adis, this_attr->address, val); error_ret: return ret ? ret : len; @@ -180,10 +62,11 @@ error_ret: static int adis16220_capture(struct iio_dev *indio_dev) { + struct adis16220_state *st = iio_priv(indio_dev); int ret; - ret = adis16220_spi_write_reg_16(indio_dev, - ADIS16220_GLOB_CMD, - 0xBF08); /* initiates a manual data capture */ + + /* initiates a manual data capture */ + ret = adis_write_reg_16(&st->adis, ADIS16220_GLOB_CMD, 0xBF08); if (ret) dev_err(&indio_dev->dev, "problem beginning capture"); @@ -192,18 +75,6 @@ static int adis16220_capture(struct iio_dev *indio_dev) return ret; } -static int adis16220_reset(struct iio_dev *indio_dev) -{ - int ret; - ret = adis16220_spi_write_reg_8(indio_dev, - ADIS16220_GLOB_CMD, - ADIS16220_GLOB_CMD_SW_RESET); - if (ret) - dev_err(&indio_dev->dev, "problem resetting device"); - - return ret; -} - static ssize_t adis16220_write_capture(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) @@ -224,81 +95,6 @@ static ssize_t adis16220_write_capture(struct device *dev, return len; } -static int adis16220_check_status(struct iio_dev *indio_dev) -{ - u16 status; - int ret; - - ret = adis16220_spi_read_reg_16(indio_dev, ADIS16220_DIAG_STAT, - &status); - - if (ret < 0) { - dev_err(&indio_dev->dev, "Reading status failed\n"); - goto error_ret; - } - ret = status & 0x7F; - - if (status & ADIS16220_DIAG_STAT_VIOLATION) - dev_err(&indio_dev->dev, - "Capture period violation/interruption\n"); - if (status & ADIS16220_DIAG_STAT_SPI_FAIL) - dev_err(&indio_dev->dev, "SPI failure\n"); - if (status & ADIS16220_DIAG_STAT_FLASH_UPT) - dev_err(&indio_dev->dev, "Flash update failed\n"); - if (status & ADIS16220_DIAG_STAT_POWER_HIGH) - dev_err(&indio_dev->dev, "Power supply above 3.625V\n"); - if (status & ADIS16220_DIAG_STAT_POWER_LOW) - dev_err(&indio_dev->dev, "Power supply below 3.15V\n"); - -error_ret: - return ret; -} - -static int adis16220_self_test(struct iio_dev *indio_dev) -{ - int ret; - ret = adis16220_spi_write_reg_16(indio_dev, - ADIS16220_MSC_CTRL, - ADIS16220_MSC_CTRL_SELF_TEST_EN); - if (ret) { - dev_err(&indio_dev->dev, "problem starting self test"); - goto err_ret; - } - - adis16220_check_status(indio_dev); - -err_ret: - return ret; -} - -static int adis16220_initial_setup(struct iio_dev *indio_dev) -{ - int ret; - - /* Do self test */ - ret = adis16220_self_test(indio_dev); - if (ret) { - dev_err(&indio_dev->dev, "self test failure"); - goto err_ret; - } - - /* Read status register to check the result */ - ret = adis16220_check_status(indio_dev); - if (ret) { - adis16220_reset(indio_dev); - dev_err(&indio_dev->dev, "device not playing ball -> reset"); - msleep(ADIS16220_STARTUP_DELAY); - ret = adis16220_check_status(indio_dev); - if (ret) { - dev_err(&indio_dev->dev, "giving up"); - goto err_ret; - } - } - -err_ret: - return ret; -} - static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev, char *buf, loff_t off, @@ -335,7 +131,7 @@ static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev, count = ADIS16220_CAPTURE_SIZE - off; /* write the begin position of capture buffer */ - ret = adis16220_spi_write_reg_16(indio_dev, + ret = adis_write_reg_16(&st->adis, ADIS16220_CAPT_PNTR, off > 1); if (ret) @@ -344,8 +140,9 @@ static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev, /* read count/2 values from capture buffer */ mutex_lock(&st->buf_lock); + for (i = 0; i < count; i += 2) { - st->tx[i] = ADIS16220_READ_REG(addr); + st->tx[i] = ADIS_READ_REG(addr); st->tx[i + 1] = 0; } xfers[1].len = count; @@ -353,7 +150,7 @@ static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev, spi_message_init(&msg); spi_message_add_tail(&xfers[0], &msg); spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); + ret = spi_sync(st->adis.spi, &msg); if (ret) { mutex_unlock(&st->buf_lock); @@ -474,6 +271,8 @@ static int adis16220_read_raw(struct iio_dev *indio_dev, int *val, int *val2, long mask) { + struct adis16220_state *st = iio_priv(indio_dev); + const struct adis16220_address_spec *addr; int ret = -EINVAL; int addrind = 0; u16 uval; @@ -518,28 +317,21 @@ static int adis16220_read_raw(struct iio_dev *indio_dev, default: return -EINVAL; } - if (adis16220_addresses[chan->address][addrind].sign) { - ret = adis16220_spi_read_reg_16(indio_dev, - adis16220_addresses[chan - ->address] - [addrind].addr, - &sval); + addr = &adis16220_addresses[chan->address][addrind]; + if (addr->sign) { + ret = adis_read_reg_16(&st->adis, addr->addr, &sval); if (ret) return ret; - bits = adis16220_addresses[chan->address][addrind].bits; + bits = addr->bits; sval &= (1 << bits) - 1; sval = (s16)(sval << (16 - bits)) >> (16 - bits); *val = sval; return IIO_VAL_INT; } else { - ret = adis16220_spi_read_reg_16(indio_dev, - adis16220_addresses[chan - ->address] - [addrind].addr, - &uval); + ret = adis_read_reg_16(&st->adis, addr->addr, &uval); if (ret) return ret; - bits = adis16220_addresses[chan->address][addrind].bits; + bits = addr->bits; uval &= (1 << bits) - 1; *val = uval; return IIO_VAL_INT; @@ -603,7 +395,33 @@ static const struct iio_info adis16220_info = { .read_raw = &adis16220_read_raw, }; -static int __devinit adis16220_probe(struct spi_device *spi) +static const char * const adis16220_status_error_msgs[] = { + [ADIS16220_DIAG_STAT_VIOLATION_BIT] = "Capture period violation/interruption", + [ADIS16220_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure", + [ADIS16220_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed", + [ADIS16220_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V", + [ADIS16220_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 3.15V", +}; + +static const struct adis_data adis16220_data = { + .read_delay = 35, + .write_delay = 35, + .msc_ctrl_reg = ADIS16220_MSC_CTRL, + .glob_cmd_reg = ADIS16220_GLOB_CMD, + .diag_stat_reg = ADIS16220_DIAG_STAT, + + .self_test_mask = ADIS16220_MSC_CTRL_SELF_TEST_EN, + .startup_delay = ADIS16220_STARTUP_DELAY, + + .status_error_msgs = adis16220_status_error_msgs, + .status_error_mask = BIT(ADIS16220_DIAG_STAT_VIOLATION_BIT) | + BIT(ADIS16220_DIAG_STAT_SPI_FAIL_BIT) | + BIT(ADIS16220_DIAG_STAT_FLASH_UPT_BIT) | + BIT(ADIS16220_DIAG_STAT_POWER_HIGH_BIT) | + BIT(ADIS16220_DIAG_STAT_POWER_LOW_BIT), +}; + +static int adis16220_probe(struct spi_device *spi) { int ret; struct adis16220_state *st; @@ -620,9 +438,6 @@ static int __devinit adis16220_probe(struct spi_device *spi) /* this is only used for removal purposes */ spi_set_drvdata(spi, indio_dev); - st->us = spi; - mutex_init(&st->buf_lock); - indio_dev->name = spi->dev.driver->name; indio_dev->dev.parent = &spi->dev; indio_dev->info = &adis16220_info; @@ -646,8 +461,11 @@ static int __devinit adis16220_probe(struct spi_device *spi) if (ret) goto error_rm_adc1_bin; + ret = adis_init(&st->adis, indio_dev, spi, &adis16220_data); + if (ret) + goto error_rm_adc2_bin; /* Get the device into a sane initial state */ - ret = adis16220_initial_setup(indio_dev); + ret = adis_initial_startup(&st->adis); if (ret) goto error_rm_adc2_bin; return 0; @@ -666,7 +484,7 @@ error_ret: return ret; } -static int __devexit adis16220_remove(struct spi_device *spi) +static int adis16220_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); @@ -685,7 +503,7 @@ static struct spi_driver adis16220_driver = { .owner = THIS_MODULE, }, .probe = adis16220_probe, - .remove = __devexit_p(adis16220_remove), + .remove = adis16220_remove, }; module_spi_driver(adis16220_driver); diff --git a/drivers/staging/iio/accel/adis16240.h b/drivers/staging/iio/accel/adis16240.h index 3fabcc0b3471..d442d49f51f4 100644 --- a/drivers/staging/iio/accel/adis16240.h +++ b/drivers/staging/iio/accel/adis16240.h @@ -3,9 +3,6 @@ #define ADIS16240_STARTUP_DELAY 220 /* ms */ -#define ADIS16240_READ_REG(a) a -#define ADIS16240_WRITE_REG(a) ((a) | 0x80) - /* Flash memory write count */ #define ADIS16240_FLASH_CNT 0x00 /* Output, power supply */ @@ -75,8 +72,6 @@ /* System command */ #define ADIS16240_GLOB_CMD 0x4A -#define ADIS16240_OUTPUTS 6 - /* MSC_CTRL */ /* Enables sum-of-squares output (XYZPEAK_OUT) */ #define ADIS16240_MSC_CTRL_XYZPEAK_OUT_EN (1 << 15) @@ -101,17 +96,17 @@ /* Flash test, checksum flag: 1 = mismatch, 0 = match */ #define ADIS16240_DIAG_STAT_CHKSUM (1<<6) /* Power-on, self-test flag: 1 = failure, 0 = pass */ -#define ADIS16240_DIAG_STAT_PWRON_FAIL (1<<5) +#define ADIS16240_DIAG_STAT_PWRON_FAIL_BIT 5 /* Power-on self-test: 1 = in-progress, 0 = complete */ #define ADIS16240_DIAG_STAT_PWRON_BUSY (1<<4) /* SPI communications failure */ -#define ADIS16240_DIAG_STAT_SPI_FAIL (1<<3) +#define ADIS16240_DIAG_STAT_SPI_FAIL_BIT 3 /* Flash update failure */ -#define ADIS16240_DIAG_STAT_FLASH_UPT (1<<2) +#define ADIS16240_DIAG_STAT_FLASH_UPT_BIT 2 /* Power supply above 3.625 V */ -#define ADIS16240_DIAG_STAT_POWER_HIGH (1<<1) +#define ADIS16240_DIAG_STAT_POWER_HIGH_BIT 1 /* Power supply below 3.15 V */ -#define ADIS16240_DIAG_STAT_POWER_LOW (1<<0) +#define ADIS16240_DIAG_STAT_POWER_LOW_BIT 0 /* GLOB_CMD */ #define ADIS16240_GLOB_CMD_RESUME (1<<8) @@ -120,77 +115,15 @@ #define ADIS16240_ERROR_ACTIVE (1<<14) -#define ADIS16240_MAX_TX 24 -#define ADIS16240_MAX_RX 24 - -/** - * struct adis16240_state - device instance specific data - * @us: actual spi_device - * @trig: data ready trigger registered with iio - * @tx: transmit buffer - * @rx: receive buffer - * @buf_lock: mutex to protect tx and rx - **/ -struct adis16240_state { - struct spi_device *us; - struct iio_trigger *trig; - struct mutex buf_lock; - u8 tx[ADIS16240_MAX_TX] ____cacheline_aligned; - u8 rx[ADIS16240_MAX_RX]; -}; - -int adis16240_set_irq(struct iio_dev *indio_dev, bool enable); - /* At the moment triggers are only used for ring buffer * filling. This may change! */ -#define ADIS16240_SCAN_SUPPLY 0 -#define ADIS16240_SCAN_ACC_X 1 -#define ADIS16240_SCAN_ACC_Y 2 -#define ADIS16240_SCAN_ACC_Z 3 +#define ADIS16240_SCAN_ACC_X 0 +#define ADIS16240_SCAN_ACC_Y 1 +#define ADIS16240_SCAN_ACC_Z 2 +#define ADIS16240_SCAN_SUPPLY 3 #define ADIS16240_SCAN_AUX_ADC 4 #define ADIS16240_SCAN_TEMP 5 -#ifdef CONFIG_IIO_BUFFER -void adis16240_remove_trigger(struct iio_dev *indio_dev); -int adis16240_probe_trigger(struct iio_dev *indio_dev); - -ssize_t adis16240_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf); - - -int adis16240_configure_ring(struct iio_dev *indio_dev); -void adis16240_unconfigure_ring(struct iio_dev *indio_dev); - -#else /* CONFIG_IIO_BUFFER */ - -static inline void adis16240_remove_trigger(struct iio_dev *indio_dev) -{ -} - -static inline int adis16240_probe_trigger(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline ssize_t -adis16240_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return 0; -} - -static int adis16240_configure_ring(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline void adis16240_unconfigure_ring(struct iio_dev *indio_dev) -{ -} - -#endif /* CONFIG_IIO_BUFFER */ #endif /* SPI_ADIS16240_H_ */ diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c index 35e093973d5c..e97fa0b0233d 100644 --- a/drivers/staging/iio/accel/adis16240_core.c +++ b/drivers/staging/iio/accel/adis16240_core.c @@ -22,151 +22,29 @@ #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> #include <linux/iio/buffer.h> +#include <linux/iio/imu/adis.h> #include "adis16240.h" -#define DRIVER_NAME "adis16240" - -static int adis16240_check_status(struct iio_dev *indio_dev); - -/** - * adis16240_spi_write_reg_8() - write single byte to a register - * @indio_dev: iio_dev associated with device - * @reg_address: the address of the register to be written - * @val: the value to write - **/ -static int adis16240_spi_write_reg_8(struct iio_dev *indio_dev, - u8 reg_address, - u8 val) -{ - int ret; - struct adis16240_state *st = iio_priv(indio_dev); - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16240_WRITE_REG(reg_address); - st->tx[1] = val; - - ret = spi_write(st->us, st->tx, 2); - mutex_unlock(&st->buf_lock); - - return ret; -} - -/** - * adis16240_spi_write_reg_16() - write 2 bytes to a pair of registers - * @indio_dev: iio_dev for this device - * @reg_address: the address of the lower of the two registers. Second register - * is assumed to have address one greater. - * @val: value to be written - **/ -static int adis16240_spi_write_reg_16(struct iio_dev *indio_dev, - u8 lower_reg_address, - u16 value) -{ - int ret; - struct spi_message msg; - struct adis16240_state *st = iio_priv(indio_dev); - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .delay_usecs = 35, - }, { - .tx_buf = st->tx + 2, - .bits_per_word = 8, - .len = 2, - .delay_usecs = 35, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16240_WRITE_REG(lower_reg_address); - st->tx[1] = value & 0xFF; - st->tx[2] = ADIS16240_WRITE_REG(lower_reg_address + 1); - st->tx[3] = (value >> 8) & 0xFF; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); - mutex_unlock(&st->buf_lock); - - return ret; -} - -/** - * adis16240_spi_read_reg_16() - read 2 bytes from a 16-bit register - * @indio_dev: iio_dev for this device - * @reg_address: the address of the lower of the two registers. Second register - * is assumed to have address one greater. - * @val: somewhere to pass back the value read - **/ -static int adis16240_spi_read_reg_16(struct iio_dev *indio_dev, - u8 lower_reg_address, - u16 *val) -{ - struct spi_message msg; - struct adis16240_state *st = iio_priv(indio_dev); - int ret; - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .delay_usecs = 35, - }, { - .rx_buf = st->rx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .delay_usecs = 35, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16240_READ_REG(lower_reg_address); - st->tx[1] = 0; - st->tx[2] = 0; - st->tx[3] = 0; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); - if (ret) { - dev_err(&st->us->dev, - "problem when reading 16 bit register 0x%02X", - lower_reg_address); - goto error_ret; - } - *val = (st->rx[0] << 8) | st->rx[1]; - -error_ret: - mutex_unlock(&st->buf_lock); - return ret; -} - static ssize_t adis16240_spi_read_signed(struct device *dev, struct device_attribute *attr, char *buf, unsigned bits) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct adis *st = iio_priv(indio_dev); int ret; s16 val = 0; unsigned shift = 16 - bits; struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - ret = adis16240_spi_read_reg_16(indio_dev, + ret = adis_read_reg_16(st, this_attr->address, (u16 *)&val); if (ret) return ret; if (val & ADIS16240_ERROR_ACTIVE) - adis16240_check_status(indio_dev); + adis_check_status(st); val = ((s16)(val << shift) >> shift); return sprintf(buf, "%d\n", val); @@ -187,152 +65,16 @@ static ssize_t adis16240_read_12bit_signed(struct device *dev, return ret; } -static int adis16240_reset(struct iio_dev *indio_dev) -{ - int ret; - ret = adis16240_spi_write_reg_8(indio_dev, - ADIS16240_GLOB_CMD, - ADIS16240_GLOB_CMD_SW_RESET); - if (ret) - dev_err(&indio_dev->dev, "problem resetting device"); - - return ret; -} - -int adis16240_set_irq(struct iio_dev *indio_dev, bool enable) -{ - int ret = 0; - u16 msc; - - ret = adis16240_spi_read_reg_16(indio_dev, - ADIS16240_MSC_CTRL, &msc); - if (ret) - goto error_ret; - - msc |= ADIS16240_MSC_CTRL_ACTIVE_HIGH; - msc &= ~ADIS16240_MSC_CTRL_DATA_RDY_DIO2; - if (enable) - msc |= ADIS16240_MSC_CTRL_DATA_RDY_EN; - else - msc &= ~ADIS16240_MSC_CTRL_DATA_RDY_EN; - - ret = adis16240_spi_write_reg_16(indio_dev, - ADIS16240_MSC_CTRL, msc); - -error_ret: - return ret; -} - -static int adis16240_self_test(struct iio_dev *indio_dev) -{ - int ret; - ret = adis16240_spi_write_reg_16(indio_dev, - ADIS16240_MSC_CTRL, - ADIS16240_MSC_CTRL_SELF_TEST_EN); - if (ret) { - dev_err(&indio_dev->dev, "problem starting self test"); - goto err_ret; - } - - msleep(ADIS16240_STARTUP_DELAY); - - adis16240_check_status(indio_dev); - -err_ret: - return ret; -} - -static int adis16240_check_status(struct iio_dev *indio_dev) -{ - u16 status; - int ret; - struct device *dev = &indio_dev->dev; - - ret = adis16240_spi_read_reg_16(indio_dev, - ADIS16240_DIAG_STAT, &status); - - if (ret < 0) { - dev_err(dev, "Reading status failed\n"); - goto error_ret; - } - - ret = status & 0x2F; - if (status & ADIS16240_DIAG_STAT_PWRON_FAIL) - dev_err(dev, "Power-on, self-test fail\n"); - if (status & ADIS16240_DIAG_STAT_SPI_FAIL) - dev_err(dev, "SPI failure\n"); - if (status & ADIS16240_DIAG_STAT_FLASH_UPT) - dev_err(dev, "Flash update failed\n"); - if (status & ADIS16240_DIAG_STAT_POWER_HIGH) - dev_err(dev, "Power supply above 3.625V\n"); - if (status & ADIS16240_DIAG_STAT_POWER_LOW) - dev_err(dev, "Power supply below 2.225V\n"); - -error_ret: - return ret; -} - -static int adis16240_initial_setup(struct iio_dev *indio_dev) -{ - int ret; - struct device *dev = &indio_dev->dev; - - /* Disable IRQ */ - ret = adis16240_set_irq(indio_dev, false); - if (ret) { - dev_err(dev, "disable irq failed"); - goto err_ret; - } - - /* Do self test */ - ret = adis16240_self_test(indio_dev); - if (ret) { - dev_err(dev, "self test failure"); - goto err_ret; - } - - /* Read status register to check the result */ - ret = adis16240_check_status(indio_dev); - if (ret) { - adis16240_reset(indio_dev); - dev_err(dev, "device not playing ball -> reset"); - msleep(ADIS16240_STARTUP_DELAY); - ret = adis16240_check_status(indio_dev); - if (ret) { - dev_err(dev, "giving up"); - goto err_ret; - } - } - -err_ret: - return ret; -} - static IIO_DEVICE_ATTR(in_accel_xyz_squared_peak_raw, S_IRUGO, adis16240_read_12bit_signed, NULL, ADIS16240_XYZPEAK_OUT); static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("4096"); -enum adis16240_chan { - in_supply, - in_aux, - accel_x, - accel_y, - accel_z, - temp, -}; - -static const u8 adis16240_addresses[6][3] = { - [in_supply] = { ADIS16240_SUPPLY_OUT }, - [in_aux] = { ADIS16240_AUX_ADC }, - [accel_x] = { ADIS16240_XACCL_OUT, ADIS16240_XACCL_OFF, - ADIS16240_XPEAK_OUT }, - [accel_y] = { ADIS16240_YACCL_OUT, ADIS16240_YACCL_OFF, - ADIS16240_YPEAK_OUT }, - [accel_z] = { ADIS16240_ZACCL_OUT, ADIS16240_ZACCL_OFF, - ADIS16240_ZPEAK_OUT }, - [temp] = { ADIS16240_TEMP_OUT }, +static const u8 adis16240_addresses[][2] = { + [ADIS16240_SCAN_ACC_X] = { ADIS16240_XACCL_OFF, ADIS16240_XPEAK_OUT }, + [ADIS16240_SCAN_ACC_Y] = { ADIS16240_YACCL_OFF, ADIS16240_YPEAK_OUT }, + [ADIS16240_SCAN_ACC_Z] = { ADIS16240_ZACCL_OFF, ADIS16240_ZPEAK_OUT }, }; static int adis16240_read_raw(struct iio_dev *indio_dev, @@ -340,6 +82,7 @@ static int adis16240_read_raw(struct iio_dev *indio_dev, int *val, int *val2, long mask) { + struct adis *st = iio_priv(indio_dev); int ret; int bits; u8 addr; @@ -347,29 +90,8 @@ static int adis16240_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); - addr = adis16240_addresses[chan->address][0]; - ret = adis16240_spi_read_reg_16(indio_dev, addr, &val16); - if (ret) { - mutex_unlock(&indio_dev->mlock); - return ret; - } - - if (val16 & ADIS16240_ERROR_ACTIVE) { - ret = adis16240_check_status(indio_dev); - if (ret) { - mutex_unlock(&indio_dev->mlock); - return ret; - } - } - val16 = val16 & ((1 << chan->scan_type.realbits) - 1); - if (chan->scan_type.sign == 's') - val16 = (s16)(val16 << - (16 - chan->scan_type.realbits)) >> - (16 - chan->scan_type.realbits); - *val = val16; - mutex_unlock(&indio_dev->mlock); - return IIO_VAL_INT; + return adis_single_conversion(indio_dev, chan, + ADIS16240_ERROR_ACTIVE, val); case IIO_CHAN_INFO_SCALE: switch (chan->type) { case IIO_VOLTAGE: @@ -402,8 +124,8 @@ static int adis16240_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_CALIBBIAS: bits = 10; mutex_lock(&indio_dev->mlock); - addr = adis16240_addresses[chan->address][1]; - ret = adis16240_spi_read_reg_16(indio_dev, addr, &val16); + addr = adis16240_addresses[chan->scan_index][0]; + ret = adis_read_reg_16(st, addr, &val16); if (ret) { mutex_unlock(&indio_dev->mlock); return ret; @@ -416,8 +138,8 @@ static int adis16240_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_PEAK: bits = 10; mutex_lock(&indio_dev->mlock); - addr = adis16240_addresses[chan->address][2]; - ret = adis16240_spi_read_reg_16(indio_dev, addr, &val16); + addr = adis16240_addresses[chan->scan_index][1]; + ret = adis_read_reg_16(st, addr, &val16); if (ret) { mutex_unlock(&indio_dev->mlock); return ret; @@ -437,104 +159,32 @@ static int adis16240_write_raw(struct iio_dev *indio_dev, int val2, long mask) { + struct adis *st = iio_priv(indio_dev); int bits = 10; s16 val16; u8 addr; switch (mask) { case IIO_CHAN_INFO_CALIBBIAS: val16 = val & ((1 << bits) - 1); - addr = adis16240_addresses[chan->address][1]; - return adis16240_spi_write_reg_16(indio_dev, addr, val16); + addr = adis16240_addresses[chan->scan_index][0]; + return adis_write_reg_16(st, addr, val16); } return -EINVAL; } static const struct iio_chan_spec adis16240_channels[] = { - { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 0, - .extend_name = "supply", - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - .address = in_supply, - .scan_index = ADIS16240_SCAN_SUPPLY, - .scan_type = { - .sign = 'u', - .realbits = 10, - .storagebits = 16, - }, - }, { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, - .address = in_aux, - .scan_index = ADIS16240_SCAN_AUX_ADC, - .scan_type = { - .sign = 'u', - .realbits = 10, - .storagebits = 16, - }, - }, { - .type = IIO_ACCEL, - .modified = 1, - .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | + ADIS_SUPPLY_CHAN(ADIS16240_SUPPLY_OUT, ADIS16240_SCAN_SUPPLY, 10), + ADIS_AUX_ADC_CHAN(ADIS16240_AUX_ADC, ADIS16240_SCAN_AUX_ADC, 10), + ADIS_ACCEL_CHAN(X, ADIS16240_XACCL_OUT, ADIS16240_SCAN_ACC_X, IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | - IIO_CHAN_INFO_PEAK_SEPARATE_BIT, - .address = accel_x, - .scan_index = ADIS16240_SCAN_ACC_X, - .scan_type = { - .sign = 's', - .realbits = 10, - .storagebits = 16, - }, - }, { - .type = IIO_ACCEL, - .modified = 1, - .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | + IIO_CHAN_INFO_PEAK_SEPARATE_BIT, 10), + ADIS_ACCEL_CHAN(Y, ADIS16240_YACCL_OUT, ADIS16240_SCAN_ACC_Y, IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | - IIO_CHAN_INFO_PEAK_SEPARATE_BIT, - .address = accel_y, - .scan_index = ADIS16240_SCAN_ACC_Y, - .scan_type = { - .sign = 's', - .realbits = 10, - .storagebits = 16, - }, - }, { - .type = IIO_ACCEL, - .modified = 1, - .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | + IIO_CHAN_INFO_PEAK_SEPARATE_BIT, 10), + ADIS_ACCEL_CHAN(Z, ADIS16240_ZACCL_OUT, ADIS16240_SCAN_ACC_Z, IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | - IIO_CHAN_INFO_PEAK_SEPARATE_BIT, - .address = accel_z, - .scan_index = ADIS16240_SCAN_ACC_Z, - .scan_type = { - .sign = 's', - .realbits = 10, - .storagebits = 16, - }, - }, { - .type = IIO_TEMP, - .indexed = 1, - .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - .address = temp, - .scan_index = ADIS16240_SCAN_TEMP, - .scan_type = { - .sign = 'u', - .realbits = 10, - .storagebits = 16, - }, - }, + IIO_CHAN_INFO_PEAK_SEPARATE_BIT, 10), + ADIS_TEMP_CHAN(ADIS16240_TEMP_OUT, ADIS16240_SCAN_TEMP, 10), IIO_CHAN_SOFT_TIMESTAMP(6) }; @@ -552,13 +202,40 @@ static const struct iio_info adis16240_info = { .attrs = &adis16240_attribute_group, .read_raw = &adis16240_read_raw, .write_raw = &adis16240_write_raw, + .update_scan_mode = adis_update_scan_mode, .driver_module = THIS_MODULE, }; -static int __devinit adis16240_probe(struct spi_device *spi) +static const char * const adis16240_status_error_msgs[] = { + [ADIS16240_DIAG_STAT_PWRON_FAIL_BIT] = "Power on, self-test failed", + [ADIS16240_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure", + [ADIS16240_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed", + [ADIS16240_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V", + [ADIS16240_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 2.225V", +}; + +static const struct adis_data adis16240_data = { + .write_delay = 35, + .read_delay = 35, + .msc_ctrl_reg = ADIS16240_MSC_CTRL, + .glob_cmd_reg = ADIS16240_GLOB_CMD, + .diag_stat_reg = ADIS16240_DIAG_STAT, + + .self_test_mask = ADIS16240_MSC_CTRL_SELF_TEST_EN, + .startup_delay = ADIS16240_STARTUP_DELAY, + + .status_error_msgs = adis16240_status_error_msgs, + .status_error_mask = BIT(ADIS16240_DIAG_STAT_PWRON_FAIL_BIT) | + BIT(ADIS16240_DIAG_STAT_SPI_FAIL_BIT) | + BIT(ADIS16240_DIAG_STAT_FLASH_UPT_BIT) | + BIT(ADIS16240_DIAG_STAT_POWER_HIGH_BIT) | + BIT(ADIS16240_DIAG_STAT_POWER_LOW_BIT), +}; + +static int adis16240_probe(struct spi_device *spi) { int ret; - struct adis16240_state *st; + struct adis *st; struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ @@ -571,9 +248,6 @@ static int __devinit adis16240_probe(struct spi_device *spi) /* this is only used for removal purposes */ spi_set_drvdata(spi, indio_dev); - st->us = spi; - mutex_init(&st->buf_lock); - indio_dev->name = spi->dev.driver->name; indio_dev->dev.parent = &spi->dev; indio_dev->info = &adis16240_info; @@ -581,54 +255,37 @@ static int __devinit adis16240_probe(struct spi_device *spi) indio_dev->num_channels = ARRAY_SIZE(adis16240_channels); indio_dev->modes = INDIO_DIRECT_MODE; - ret = adis16240_configure_ring(indio_dev); + ret = adis_init(st, indio_dev, spi, &adis16240_data); + if (ret) + goto error_free_dev; + ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL); if (ret) goto error_free_dev; - - ret = iio_buffer_register(indio_dev, - adis16240_channels, - ARRAY_SIZE(adis16240_channels)); - if (ret) { - printk(KERN_ERR "failed to initialize the ring\n"); - goto error_unreg_ring_funcs; - } - - if (spi->irq) { - ret = adis16240_probe_trigger(indio_dev); - if (ret) - goto error_uninitialize_ring; - } /* Get the device into a sane initial state */ - ret = adis16240_initial_setup(indio_dev); + ret = adis_initial_startup(st); if (ret) - goto error_remove_trigger; + goto error_cleanup_buffer_trigger; ret = iio_device_register(indio_dev); if (ret) - goto error_remove_trigger; + goto error_cleanup_buffer_trigger; return 0; -error_remove_trigger: - adis16240_remove_trigger(indio_dev); -error_uninitialize_ring: - iio_buffer_unregister(indio_dev); -error_unreg_ring_funcs: - adis16240_unconfigure_ring(indio_dev); +error_cleanup_buffer_trigger: + adis_cleanup_buffer_and_trigger(st, indio_dev); error_free_dev: iio_device_free(indio_dev); error_ret: return ret; } -static int __devexit adis16240_remove(struct spi_device *spi) +static int adis16240_remove(struct spi_device *spi) { - struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct adis *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); - adis16240_remove_trigger(indio_dev); - iio_buffer_unregister(indio_dev); - adis16240_unconfigure_ring(indio_dev); + adis_cleanup_buffer_and_trigger(st, indio_dev); iio_device_free(indio_dev); return 0; @@ -640,7 +297,7 @@ static struct spi_driver adis16240_driver = { .owner = THIS_MODULE, }, .probe = adis16240_probe, - .remove = __devexit_p(adis16240_remove), + .remove = adis16240_remove, }; module_spi_driver(adis16240_driver); diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c deleted file mode 100644 index caff8e25e0a2..000000000000 --- a/drivers/staging/iio/accel/adis16240_ring.c +++ /dev/null @@ -1,132 +0,0 @@ -#include <linux/export.h> -#include <linux/interrupt.h> -#include <linux/mutex.h> -#include <linux/kernel.h> -#include <linux/spi/spi.h> -#include <linux/slab.h> - -#include <linux/iio/iio.h> -#include "../ring_sw.h" -#include <linux/iio/trigger_consumer.h> -#include "adis16240.h" - -/** - * adis16240_read_ring_data() read data registers which will be placed into ring - * @indio_dev: the IIO device - * @rx: somewhere to pass back the value read - **/ -static int adis16240_read_ring_data(struct iio_dev *indio_dev, u8 *rx) -{ - struct spi_message msg; - struct adis16240_state *st = iio_priv(indio_dev); - struct spi_transfer xfers[ADIS16240_OUTPUTS + 1]; - int ret; - int i; - - mutex_lock(&st->buf_lock); - - spi_message_init(&msg); - - memset(xfers, 0, sizeof(xfers)); - for (i = 0; i <= ADIS16240_OUTPUTS; i++) { - xfers[i].bits_per_word = 8; - xfers[i].cs_change = 1; - xfers[i].len = 2; - xfers[i].delay_usecs = 30; - xfers[i].tx_buf = st->tx + 2 * i; - st->tx[2 * i] - = ADIS16240_READ_REG(ADIS16240_SUPPLY_OUT + 2 * i); - st->tx[2 * i + 1] = 0; - if (i >= 1) - xfers[i].rx_buf = rx + 2 * (i - 1); - spi_message_add_tail(&xfers[i], &msg); - } - - ret = spi_sync(st->us, &msg); - if (ret) - dev_err(&st->us->dev, "problem when burst reading"); - - mutex_unlock(&st->buf_lock); - - return ret; -} - -static irqreturn_t adis16240_trigger_handler(int irq, void *p) -{ - struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->indio_dev; - struct adis16240_state *st = iio_priv(indio_dev); - - int i = 0; - s16 *data; - - data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); - if (data == NULL) { - dev_err(&st->us->dev, "memory alloc failed in ring bh"); - goto done; - } - - if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) && - adis16240_read_ring_data(indio_dev, st->rx) >= 0) - for (; i < bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength); i++) - data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2])); - - /* Guaranteed to be aligned with 8 byte boundary */ - if (indio_dev->scan_timestamp) - *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - - iio_push_to_buffer(indio_dev->buffer, (u8 *)data); - - kfree(data); -done: - iio_trigger_notify_done(indio_dev->trig); - - return IRQ_HANDLED; -} - -void adis16240_unconfigure_ring(struct iio_dev *indio_dev) -{ - iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_sw_rb_free(indio_dev->buffer); -} - -static const struct iio_buffer_setup_ops adis16240_ring_setup_ops = { - .preenable = &iio_sw_buffer_preenable, - .postenable = &iio_triggered_buffer_postenable, - .predisable = &iio_triggered_buffer_predisable, -}; - -int adis16240_configure_ring(struct iio_dev *indio_dev) -{ - int ret = 0; - struct iio_buffer *ring; - - ring = iio_sw_rb_allocate(indio_dev); - if (!ring) { - ret = -ENOMEM; - return ret; - } - indio_dev->buffer = ring; - ring->scan_timestamp = true; - indio_dev->setup_ops = &adis16240_ring_setup_ops; - - indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, - &adis16240_trigger_handler, - IRQF_ONESHOT, - indio_dev, - "%s_consumer%d", - indio_dev->name, - indio_dev->id); - if (indio_dev->pollfunc == NULL) { - ret = -ENOMEM; - goto error_iio_sw_rb_free; - } - - indio_dev->modes |= INDIO_BUFFER_TRIGGERED; - return 0; - -error_iio_sw_rb_free: - iio_sw_rb_free(indio_dev->buffer); - return ret; -} diff --git a/drivers/staging/iio/accel/adis16240_trigger.c b/drivers/staging/iio/accel/adis16240_trigger.c deleted file mode 100644 index fa90a22b143e..000000000000 --- a/drivers/staging/iio/accel/adis16240_trigger.c +++ /dev/null @@ -1,82 +0,0 @@ -#include <linux/interrupt.h> -#include <linux/kernel.h> -#include <linux/spi/spi.h> -#include <linux/export.h> - -#include <linux/iio/iio.h> -#include <linux/iio/trigger.h> -#include "adis16240.h" - -/** - * adis16240_data_rdy_trig_poll() the event handler for the data rdy trig - **/ -static irqreturn_t adis16240_data_rdy_trig_poll(int irq, void *trig) -{ - iio_trigger_poll(trig, iio_get_time_ns()); - return IRQ_HANDLED; -} - -/** - * adis16240_data_rdy_trigger_set_state() set datardy interrupt state - **/ -static int adis16240_data_rdy_trigger_set_state(struct iio_trigger *trig, - bool state) -{ - struct iio_dev *indio_dev = trig->private_data; - - dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); - return adis16240_set_irq(indio_dev, state); -} - -static const struct iio_trigger_ops adis16240_trigger_ops = { - .owner = THIS_MODULE, - .set_trigger_state = &adis16240_data_rdy_trigger_set_state, -}; - -int adis16240_probe_trigger(struct iio_dev *indio_dev) -{ - int ret; - struct adis16240_state *st = iio_priv(indio_dev); - - st->trig = iio_trigger_alloc("adis16240-dev%d", indio_dev->id); - if (st->trig == NULL) { - ret = -ENOMEM; - goto error_ret; - } - - ret = request_irq(st->us->irq, - adis16240_data_rdy_trig_poll, - IRQF_TRIGGER_RISING, - "adis16240", - st->trig); - if (ret) - goto error_free_trig; - - st->trig->dev.parent = &st->us->dev; - st->trig->ops = &adis16240_trigger_ops; - st->trig->private_data = indio_dev; - ret = iio_trigger_register(st->trig); - - /* select default trigger */ - indio_dev->trig = st->trig; - if (ret) - goto error_free_irq; - - return 0; - -error_free_irq: - free_irq(st->us->irq, st->trig); -error_free_trig: - iio_trigger_free(st->trig); -error_ret: - return ret; -} - -void adis16240_remove_trigger(struct iio_dev *indio_dev) -{ - struct adis16240_state *st = iio_priv(indio_dev); - - iio_trigger_unregister(st->trig); - free_irq(st->us->irq, st->trig); - iio_trigger_free(st->trig); -} diff --git a/drivers/staging/iio/accel/kxsd9.c b/drivers/staging/iio/accel/kxsd9.c index fdd5fbded660..318331f08d9c 100644 --- a/drivers/staging/iio/accel/kxsd9.c +++ b/drivers/staging/iio/accel/kxsd9.c @@ -171,7 +171,7 @@ static int kxsd9_read_raw(struct iio_dev *indio_dev, *val2 = kxsd9_micro_scales[ret & KXSD9_FS_MASK]; ret = IIO_VAL_INT_PLUS_MICRO; break; - }; + } error_ret: return ret; @@ -200,7 +200,7 @@ static const struct attribute_group kxsd9_attribute_group = { .attrs = kxsd9_attributes, }; -static int __devinit kxsd9_power_up(struct kxsd9_state *st) +static int kxsd9_power_up(struct kxsd9_state *st) { int ret; @@ -222,7 +222,7 @@ static const struct iio_info kxsd9_info = { .driver_module = THIS_MODULE, }; -static int __devinit kxsd9_probe(struct spi_device *spi) +static int kxsd9_probe(struct spi_device *spi) { struct iio_dev *indio_dev; struct kxsd9_state *st; @@ -261,7 +261,7 @@ error_ret: return ret; } -static int __devexit kxsd9_remove(struct spi_device *spi) +static int kxsd9_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); iio_device_free(spi_get_drvdata(spi)); @@ -281,7 +281,7 @@ static struct spi_driver kxsd9_driver = { .owner = THIS_MODULE, }, .probe = kxsd9_probe, - .remove = __devexit_p(kxsd9_remove), + .remove = kxsd9_remove, .id_table = kxsd9_id, }; module_spi_driver(kxsd9_driver); diff --git a/drivers/staging/iio/accel/lis3l02dq.h b/drivers/staging/iio/accel/lis3l02dq.h index f9bcd41f7188..2bac7221837c 100644 --- a/drivers/staging/iio/accel/lis3l02dq.h +++ b/drivers/staging/iio/accel/lis3l02dq.h @@ -158,6 +158,7 @@ struct lis3l02dq_state { struct spi_device *us; struct iio_trigger *trig; struct mutex buf_lock; + int gpio; bool trigger_on; u8 tx[LIS3L02DQ_MAX_RX] ____cacheline_aligned; diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c index 21b0469f8bc2..37ed1b8ebb6f 100644 --- a/drivers/staging/iio/accel/lis3l02dq_core.c +++ b/drivers/staging/iio/accel/lis3l02dq_core.c @@ -15,6 +15,7 @@ #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/gpio.h> +#include <linux/of_gpio.h> #include <linux/mutex.h> #include <linux/device.h> #include <linux/kernel.h> @@ -674,7 +675,7 @@ static const struct iio_info lis3l02dq_info = { .attrs = &lis3l02dq_attribute_group, }; -static int __devinit lis3l02dq_probe(struct spi_device *spi) +static int lis3l02dq_probe(struct spi_device *spi) { int ret; struct lis3l02dq_state *st; @@ -690,6 +691,7 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi) spi_set_drvdata(spi, indio_dev); st->us = spi; + st->gpio = of_get_gpio(spi->dev.of_node, 0); mutex_init(&st->buf_lock); indio_dev->name = spi->dev.driver->name; indio_dev->dev.parent = &spi->dev; @@ -711,7 +713,7 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi) goto error_unreg_buffer_funcs; } - if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) { + if (spi->irq) { ret = request_threaded_irq(st->us->irq, &lis3l02dq_th, &lis3l02dq_event_handler, @@ -738,10 +740,10 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi) return 0; error_remove_trigger: - if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq))) + if (spi->irq) lis3l02dq_remove_trigger(indio_dev); error_free_interrupt: - if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) + if (spi->irq) free_irq(st->us->irq, indio_dev); error_uninitialize_buffer: iio_buffer_unregister(indio_dev); @@ -780,7 +782,7 @@ err_ret: } /* fixme, confirm ordering in this function */ -static int __devexit lis3l02dq_remove(struct spi_device *spi) +static int lis3l02dq_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); struct lis3l02dq_state *st = iio_priv(indio_dev); @@ -790,7 +792,7 @@ static int __devexit lis3l02dq_remove(struct spi_device *spi) lis3l02dq_disable_all_events(indio_dev); lis3l02dq_stop_device(indio_dev); - if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) + if (spi->irq) free_irq(st->us->irq, indio_dev); lis3l02dq_remove_trigger(indio_dev); @@ -808,7 +810,7 @@ static struct spi_driver lis3l02dq_driver = { .owner = THIS_MODULE, }, .probe = lis3l02dq_probe, - .remove = __devexit_p(lis3l02dq_remove), + .remove = lis3l02dq_remove, }; module_spi_driver(lis3l02dq_driver); diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index fa4190d96247..bc38651c315e 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -154,7 +154,7 @@ static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) *(s64 *)((u8 *)data + ALIGN(len, sizeof(s64))) = pf->timestamp; - iio_push_to_buffer(indio_dev->buffer, (u8 *)data); + iio_push_to_buffers(indio_dev, (u8 *)data); kfree(data); done: @@ -237,7 +237,7 @@ static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig, u8 t; __lis3l02dq_write_data_ready_config(indio_dev, state); - if (state == false) { + if (!state) { /* * A possible quirk with the handler is currently worked around * by ensuring outstanding read events are cleared. @@ -263,7 +263,7 @@ static int lis3l02dq_trig_try_reen(struct iio_trigger *trig) /* If gpio still high (or high again) * In theory possible we will need to do this several times */ for (i = 0; i < 5; i++) - if (gpio_get_value(irq_to_gpio(st->us->irq))) + if (gpio_get_value(st->gpio)) lis3l02dq_read_all(indio_dev, NULL); else break; diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c index ffd1697a9db0..414d3cad55a7 100644 --- a/drivers/staging/iio/accel/sca3000_core.c +++ b/drivers/staging/iio/accel/sca3000_core.c @@ -1139,7 +1139,7 @@ static const struct iio_info sca3000_info_with_temp = { .driver_module = THIS_MODULE, }; -static int __devinit sca3000_probe(struct spi_device *spi) +static int sca3000_probe(struct spi_device *spi) { int ret; struct sca3000_state *st; @@ -1233,7 +1233,7 @@ error_ret: return ret; } -static int __devexit sca3000_remove(struct spi_device *spi) +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); @@ -1265,7 +1265,7 @@ static struct spi_driver sca3000_driver = { .owner = THIS_MODULE, }, .probe = sca3000_probe, - .remove = __devexit_p(sca3000_remove), + .remove = sca3000_remove, .id_table = sca3000_id, }; module_spi_driver(sca3000_driver); |