diff options
Diffstat (limited to 'drivers/staging/iio/accel')
21 files changed, 629 insertions, 881 deletions
diff --git a/drivers/staging/iio/accel/Kconfig b/drivers/staging/iio/accel/Kconfig index b4e57d1bc87d..5926c03be1a5 100644 --- a/drivers/staging/iio/accel/Kconfig +++ b/drivers/staging/iio/accel/Kconfig @@ -4,29 +4,29 @@ comment "Accelerometers" config ADIS16209 - tristate "Analog Devices ADIS16209 Dual-Axis Digital Inclinometer and Accelerometer" - depends on SPI - select IIO_TRIGGER if IIO_RING_BUFFER - select IIO_SW_RING if IIO_RING_BUFFER - help - Say yes here to build support for Analog Devices adis16209 dual-axis digital inclinometer - and accelerometer. + tristate "Analog Devices ADIS16209 Dual-Axis Digital Inclinometer and Accelerometer" + depends on SPI + select IIO_TRIGGER if IIO_RING_BUFFER + select IIO_SW_RING if IIO_RING_BUFFER + help + Say yes here to build support for Analog Devices adis16209 dual-axis digital inclinometer + and accelerometer. config ADIS16220 - tristate "Analog Devices ADIS16220 Programmable Digital Vibration Sensor driver" - depends on SPI - help - Say yes here to build support for Analog Devices adis16220 programmable - digital vibration sensor. + tristate "Analog Devices ADIS16220 Programmable Digital Vibration Sensor" + depends on SPI + help + Say yes here to build support for Analog Devices adis16220 programmable + digital vibration sensor. config ADIS16240 - tristate "Analog Devices ADIS16240 Programmable Impact Sensor and Recorder" - depends on SPI - select IIO_TRIGGER if IIO_RING_BUFFER - select IIO_SW_RING if IIO_RING_BUFFER - help - Say yes here to build support for Analog Devices adis16240 programmable - impact Sensor and recorder. + tristate "Analog Devices ADIS16240 Programmable Impact Sensor and Recorder" + depends on SPI + select IIO_TRIGGER if IIO_RING_BUFFER + select IIO_SW_RING if IIO_RING_BUFFER + help + Say yes here to build support for Analog Devices adis16240 programmable + impact Sensor and recorder. config KXSD9 tristate "Kionix KXSD9 Accelerometer Driver" @@ -46,9 +46,9 @@ config LIS3L02DQ and an event interface via a character device. config SCA3000 - depends on IIO_RING_BUFFER - depends on SPI - tristate "VTI SCA3000 series accelerometers" - help - Say yes here to build support for the VTI SCA3000 series of SPI - accelerometers. These devices use a hardware ring buffer.
\ No newline at end of file + depends on IIO_RING_BUFFER + depends on SPI + tristate "VTI SCA3000 series accelerometers" + help + Say yes here to build support for the VTI SCA3000 series of SPI + accelerometers. These devices use a hardware ring buffer. diff --git a/drivers/staging/iio/accel/Makefile b/drivers/staging/iio/accel/Makefile index c34b13634c2d..ff84703a16f6 100644 --- a/drivers/staging/iio/accel/Makefile +++ b/drivers/staging/iio/accel/Makefile @@ -1,6 +1,7 @@ # # Makefile for industrial I/O accelerometer drivers # + adis16209-y := adis16209_core.o adis16209-$(CONFIG_IIO_RING_BUFFER) += adis16209_ring.o adis16209_trigger.o obj-$(CONFIG_ADIS16209) += adis16209.o @@ -19,4 +20,4 @@ lis3l02dq-$(CONFIG_IIO_RING_BUFFER) += lis3l02dq_ring.o obj-$(CONFIG_LIS3L02DQ) += lis3l02dq.o sca3000-y := sca3000_core.o sca3000_ring.o -obj-$(CONFIG_SCA3000) += sca3000.o
\ No newline at end of file +obj-$(CONFIG_SCA3000) += sca3000.o diff --git a/drivers/staging/iio/accel/accel.h b/drivers/staging/iio/accel/accel.h index 1b6e37f76200..f5f61b2497aa 100644 --- a/drivers/staging/iio/accel/accel.h +++ b/drivers/staging/iio/accel/accel.h @@ -14,158 +14,54 @@ #define IIO_DEV_ATTR_ACCEL_Z_OFFSET(_mode, _show, _store, _addr) \ IIO_DEVICE_ATTR(accel_z_offset, _mode, _show, _store, _addr) -#define IIO_DEV_ATTR_ACCEL_X_GAIN(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(accel_x_gain, _mode, _show, _store, _addr) +#define IIO_CONST_ATTR_ACCEL_SCALE(_string) \ + IIO_CONST_ATTR(accel_scale, _string) -#define IIO_DEV_ATTR_ACCEL_Y_GAIN(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(accel_y_gain, _mode, _show, _store, _addr) +#define IIO_DEV_ATTR_ACCEL_SCALE(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(accel_scale, _mode, _show, _store, _addr) -#define IIO_DEV_ATTR_ACCEL_Z_GAIN(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(accel_z_gain, _mode, _show, _store, _addr) +#define IIO_DEV_ATTR_ACCEL_X_SCALE(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(accel_x_scale, _mode, _show, _store, _addr) -#define IIO_DEV_ATTR_ACCEL(_show, _addr) \ - IIO_DEVICE_ATTR(accel_raw, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_ACCEL_X(_show, _addr) \ - IIO_DEVICE_ATTR(accel_x_raw, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_ACCEL_Y(_show, _addr) \ - IIO_DEVICE_ATTR(accel_y_raw, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_ACCEL_Z(_show, _addr) \ - IIO_DEVICE_ATTR(accel_z_raw, S_IRUGO, _show, NULL, _addr) - -/* Thresholds are somewhat chip dependent - may need quite a few defs here */ -/* For unified thresholds (shared across all directions */ - -/** - * IIO_DEV_ATTR_ACCEL_THRESH: unified threshold - * @_mode: read/write - * @_show: read detector threshold value - * @_store: write detector threshold value - * @_addr: driver specific data, typically a register address - * - * This one is for cases where as single threshold covers all directions - **/ -#define IIO_DEV_ATTR_ACCEL_THRESH(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(thresh, _mode, _show, _store, _addr) - -/** - * IIO_DEV_ATTR_ACCEL_THRESH_X: independant direction threshold, x axis - * @_mode: readable / writable - * @_show: read x axis detector threshold value - * @_store: write x axis detector threshold value - * @_addr: device driver dependant, typically a register address - **/ -#define IIO_DEV_ATTR_ACCEL_THRESH_X(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(thresh_accel_x, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_ACCEL_THRESH_Y(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(thresh_accel_y, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_ACCEL_THRESH_Z(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(thresh_accel_z, _mode, _show, _store, _addr) - -/** - * IIO_EVENT_ATTR_ACCEL_X_HIGH: threshold event, x acceleration - * @_show: read x acceleration high threshold - * @_store: write x acceleration high threshold - * @_mask: device dependant, typically a bit mask - * @_handler: the iio_handler associated with this attribute - **/ -#define IIO_EVENT_ATTR_ACCEL_X_HIGH(_show, _store, _mask, _handler) \ - IIO_EVENT_ATTR(accel_x_high, _show, _store, _mask, _handler) - -/** - * IIO_EVENT_ATTR_ACCEL_X_HIGH_SH: threshold event, x accel high, shared handler - * @_evlist: event list used to share the handler - * @_show: attribute read - * @_store: attribute write - * @_mask: driver specific data, typically a bit mask - **/ -#define IIO_EVENT_ATTR_ACCEL_X_HIGH_SH(_evlist, _show, _store, _mask) \ - IIO_EVENT_ATTR_SH(accel_x_high, _evlist, _show, _store, _mask) - -/** - * IIO_EVENT_CODE_ACCEL_X_HIGH - event code for x axis high accel threshold - **/ -#define IIO_EVENT_CODE_ACCEL_X_HIGH IIO_EVENT_CODE_ACCEL_BASE - -#define IIO_EVENT_ATTR_ACCEL_Y_HIGH(_show, _store, _mask, _handler) \ - IIO_EVENT_ATTR(accel_y_high, _show, _store, _mask, _handler) - -#define IIO_EVENT_ATTR_ACCEL_Y_HIGH_SH(_evlist, _show, _store, _mask) \ - IIO_EVENT_ATTR_SH(accel_y_high, _evlist, _show, _store, _mask) - -#define IIO_EVENT_CODE_ACCEL_Y_HIGH (IIO_EVENT_CODE_ACCEL_BASE + 1) +#define IIO_DEV_ATTR_ACCEL_Y_SCALE(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(accel_y_scale, _mode, _show, _store, _addr) -#define IIO_EVENT_ATTR_ACCEL_Z_HIGH(_show, _store, _mask, _handler) \ - IIO_EVENT_ATTR(accel_z_high, _show, _store, _mask, _handler) +#define IIO_DEV_ATTR_ACCEL_Z_SCALE(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(accel_z_scale, _mode, _show, _store, _addr) -#define IIO_EVENT_ATTR_ACCEL_Z_HIGH_SH(_evlist, _show, _store, _mask) \ - IIO_EVENT_ATTR_SH(accel_z_high, _evlist, _show, _store, _mask) +#define IIO_DEV_ATTR_ACCEL_CALIBBIAS(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(accel_calibbias, _mode, _show, _store, _addr) -#define IIO_EVENT_CODE_ACCEL_Z_HIGH (IIO_EVENT_CODE_ACCEL_BASE + 2) +#define IIO_DEV_ATTR_ACCEL_X_CALIBBIAS(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(accel_x_calibbias, _mode, _show, _store, _addr) -#define IIO_EVENT_ATTR_ACCEL_X_LOW(_show, _store, _mask, _handler) \ - IIO_EVENT_ATTR(accel_x_low, _show, _store, _mask, _handler) +#define IIO_DEV_ATTR_ACCEL_Y_CALIBBIAS(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(accel_y_calibbias, _mode, _show, _store, _addr) -#define IIO_EVENT_ATTR_ACCEL_X_LOW_SH(_evlist, _show, _store, _mask) \ - IIO_EVENT_ATTR_SH(accel_x_low, _evlist, _show, _store, _mask) +#define IIO_DEV_ATTR_ACCEL_Z_CALIBBIAS(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(accel_z_calibbias, _mode, _show, _store, _addr) -#define IIO_EVENT_CODE_ACCEL_X_LOW (IIO_EVENT_CODE_ACCEL_BASE + 3) +#define IIO_DEV_ATTR_ACCEL_CALIBSCALE(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(accel_calibscale, _mode, _show, _store, _addr) -#define IIO_EVENT_ATTR_ACCEL_Y_LOW(_show, _store, _mask, _handler) \ - IIO_EVENT_ATTR(accel_y_low, _show, _store, _mask, _handler) +#define IIO_DEV_ATTR_ACCEL_X_CALIBSCALE(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(accel_x_calibscale, _mode, _show, _store, _addr) -#define IIO_EVENT_ATTR_ACCEL_Y_LOW_SH(_evlist, _show, _store, _mask)\ - IIO_EVENT_ATTR_SH(accel_y_low, _evlist, _show, _store, _mask) +#define IIO_DEV_ATTR_ACCEL_Y_CALIBSCALE(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(accel_y_calibscale, _mode, _show, _store, _addr) -#define IIO_EVENT_CODE_ACCEL_Y_LOW (IIO_EVENT_CODE_ACCEL_BASE + 4) +#define IIO_DEV_ATTR_ACCEL_Z_CALIBSCALE(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(accel_z_calibscale, _mode, _show, _store, _addr) -#define IIO_EVENT_ATTR_ACCEL_Z_LOW(_show, _store, _mask, _handler) \ - IIO_EVENT_ATTR(accel_z_low, _show, _store, _mask, _handler) - -#define IIO_EVENT_ATTR_ACCEL_Z_LOW_SH(_evlist, _show, _store, _mask) \ - IIO_EVENT_ATTR_SH(accel_z_low, _evlist, _show, _store, _mask) - -#define IIO_EVENT_CODE_ACCEL_Z_LOW (IIO_EVENT_CODE_ACCEL_BASE + 5) - -#define IIO_EVENT_ATTR_FREE_FALL_DETECT(_show, _store, _mask, _handler) \ - IIO_EVENT_ATTR(free_fall, _show, _store, _mask, _handler) - -#define IIO_EVENT_ATTR_FREE_FALL_DETECT_SH(_evlist, _show, _store, _mask) \ - IIO_EVENT_ATTR_SH(free_fall, _evlist, _show, _store, _mask) - -#define IIO_EVENT_CODE_FREE_FALL (IIO_EVENT_CODE_ACCEL_BASE + 6) - - -#define IIO_EVENT_ATTR_ACCEL_X_ROC_HIGH_SH(_evlist, _show, _store, _mask) \ - IIO_EVENT_ATTR_SH(accel_x_roc_high, _evlist, _show, _store, _mask) - -#define IIO_EVENT_CODE_ACCEL_X_ROC_HIGH (IIO_EVENT_CODE_ACCEL_BASE + 10) - -#define IIO_EVENT_ATTR_ACCEL_X_ROC_LOW_SH(_evlist, _show, _store, _mask) \ - IIO_EVENT_ATTR_SH(accel_x_roc_low, _evlist, _show, _store, _mask) - -#define IIO_EVENT_CODE_ACCEL_X_ROC_LOW (IIO_EVENT_CODE_ACCEL_BASE + 11) - -#define IIO_EVENT_ATTR_ACCEL_Y_ROC_HIGH_SH(_evlist, _show, _store, _mask) \ - IIO_EVENT_ATTR_SH(accel_y_roc_high, _evlist, _show, _store, _mask) - -#define IIO_EVENT_CODE_ACCEL_Y_ROC_HIGH (IIO_EVENT_CODE_ACCEL_BASE + 12) - -#define IIO_EVENT_ATTR_ACCEL_Y_ROC_LOW_SH(_evlist, _show, _store, _mask) \ - IIO_EVENT_ATTR_SH(accel_y_roc_low, _evlist, _show, _store, _mask) - -#define IIO_EVENT_CODE_ACCEL_Y_ROC_LOW (IIO_EVENT_CODE_ACCEL_BASE + 13) +#define IIO_DEV_ATTR_ACCEL(_show, _addr) \ + IIO_DEVICE_ATTR(accel_raw, S_IRUGO, _show, NULL, _addr) -#define IIO_EVENT_ATTR_ACCEL_Z_ROC_HIGH_SH(_evlist, _show, _store, _mask) \ - IIO_EVENT_ATTR_SH(accel_z_roc_high, _evlist, _show, _store, _mask) +#define IIO_DEV_ATTR_ACCEL_X(_show, _addr) \ + IIO_DEVICE_ATTR(accel_x_raw, S_IRUGO, _show, NULL, _addr) -#define IIO_EVENT_CODE_ACCEL_Z_ROC_HIGH (IIO_EVENT_CODE_ACCEL_BASE + 14) +#define IIO_DEV_ATTR_ACCEL_Y(_show, _addr) \ + IIO_DEVICE_ATTR(accel_y_raw, S_IRUGO, _show, NULL, _addr) -#define IIO_EVENT_ATTR_ACCEL_Z_ROC_LOW_SH(_evlist, _show, _store, _mask) \ - IIO_EVENT_ATTR_SH(accel_z_roc_low, _evlist, _show, _store, _mask) +#define IIO_DEV_ATTR_ACCEL_Z(_show, _addr) \ + IIO_DEVICE_ATTR(accel_z_raw, S_IRUGO, _show, NULL, _addr) -#define IIO_EVENT_CODE_ACCEL_Z_ROC_LOW (IIO_EVENT_CODE_ACCEL_BASE + 15) diff --git a/drivers/staging/iio/accel/adis16209.h b/drivers/staging/iio/accel/adis16209.h index 877fd2a48380..4e97596620ef 100644 --- a/drivers/staging/iio/accel/adis16209.h +++ b/drivers/staging/iio/accel/adis16209.h @@ -105,8 +105,6 @@ * struct adis16209_state - device instance specific data * @us: actual spi_device * @work_trigger_to_ring: bh for triggered event handling - * @work_cont_thresh: CLEAN - * @inter: used to check if new interrupt has been triggered * @last_timestamp: passing timestamp from th to bh of interrupt handler * @indio_dev: industrial I/O device structure * @trig: data ready trigger registered with iio @@ -117,7 +115,6 @@ struct adis16209_state { struct spi_device *us; struct work_struct work_trigger_to_ring; - struct iio_work_cont work_cont_thresh; s64 last_timestamp; struct iio_dev *indio_dev; struct iio_trigger *trig; @@ -129,16 +126,15 @@ struct adis16209_state { int adis16209_set_irq(struct device *dev, bool enable); #ifdef CONFIG_IIO_RING_BUFFER -enum adis16209_scan { - ADIS16209_SCAN_SUPPLY, - ADIS16209_SCAN_ACC_X, - ADIS16209_SCAN_ACC_Y, - ADIS16209_SCAN_AUX_ADC, - ADIS16209_SCAN_TEMP, - ADIS16209_SCAN_INCLI_X, - ADIS16209_SCAN_INCLI_Y, - ADIS16209_SCAN_ROT, -}; + +#define ADIS16209_SCAN_SUPPLY 0 +#define ADIS16209_SCAN_ACC_X 1 +#define ADIS16209_SCAN_ACC_Y 2 +#define ADIS16209_SCAN_AUX_ADC 3 +#define ADIS16209_SCAN_TEMP 4 +#define ADIS16209_SCAN_INCLI_X 5 +#define ADIS16209_SCAN_INCLI_Y 6 +#define ADIS16209_SCAN_ROT 7 void adis16209_remove_trigger(struct iio_dev *indio_dev); int adis16209_probe_trigger(struct iio_dev *indio_dev); @@ -150,8 +146,6 @@ ssize_t adis16209_read_data_from_ring(struct device *dev, int adis16209_configure_ring(struct iio_dev *indio_dev); void adis16209_unconfigure_ring(struct iio_dev *indio_dev); -int adis16209_initialize_ring(struct iio_ring_buffer *ring); -void adis16209_uninitialize_ring(struct iio_ring_buffer *ring); #else /* CONFIG_IIO_RING_BUFFER */ static inline void adis16209_remove_trigger(struct iio_dev *indio_dev) @@ -180,14 +174,5 @@ static inline void adis16209_unconfigure_ring(struct iio_dev *indio_dev) { } -static inline int adis16209_initialize_ring(struct iio_ring_buffer *ring) -{ - return 0; -} - -static inline void adis16209_uninitialize_ring(struct iio_ring_buffer *ring) -{ -} - #endif /* CONFIG_IIO_RING_BUFFER */ #endif /* SPI_ADIS16209_H_ */ diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c index ac375c50f56f..e4ac956208a6 100644 --- a/drivers/staging/iio/accel/adis16209_core.c +++ b/drivers/staging/iio/accel/adis16209_core.c @@ -14,12 +14,13 @@ #include <linux/device.h> #include <linux/kernel.h> #include <linux/spi/spi.h> - +#include <linux/slab.h> #include <linux/sysfs.h> #include <linux/list.h> #include "../iio.h" #include "../sysfs.h" +#include "../ring_generic.h" #include "accel.h" #include "inclinometer.h" #include "../gyro/gyro.h" @@ -76,11 +77,13 @@ static int adis16209_spi_write_reg_16(struct device *dev, .bits_per_word = 8, .len = 2, .cs_change = 1, + .delay_usecs = 30, }, { .tx_buf = st->tx + 2, .bits_per_word = 8, .len = 2, .cs_change = 1, + .delay_usecs = 30, }, }; @@ -120,13 +123,13 @@ static int adis16209_spi_read_reg_16(struct device *dev, .bits_per_word = 8, .len = 2, .cs_change = 1, - .delay_usecs = 20, + .delay_usecs = 30, }, { .rx_buf = st->rx, .bits_per_word = 8, .len = 2, .cs_change = 1, - .delay_usecs = 20, + .delay_usecs = 30, }, }; @@ -388,51 +391,43 @@ err_ret: return ret; } -static IIO_DEV_ATTR_IN_NAMED_RAW(supply, adis16209_read_14bit_unsigned, +static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16209_read_14bit_unsigned, ADIS16209_SUPPLY_OUT); -static IIO_CONST_ATTR(in_supply_scale, "0.30518"); -static IIO_DEV_ATTR_IN_RAW(0, adis16209_read_12bit_unsigned, +static IIO_CONST_ATTR_IN_NAMED_SCALE(0, supply, "0.30518"); +static IIO_DEV_ATTR_IN_RAW(1, adis16209_read_12bit_unsigned, ADIS16209_AUX_ADC); -static IIO_CONST_ATTR(in0_scale, "0.6105"); +static IIO_CONST_ATTR(in1_scale, "0.6105"); static IIO_DEV_ATTR_ACCEL_X(adis16209_read_14bit_signed, ADIS16209_XACCL_OUT); static IIO_DEV_ATTR_ACCEL_Y(adis16209_read_14bit_signed, ADIS16209_YACCL_OUT); -static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO, +static IIO_DEV_ATTR_ACCEL_X_CALIBBIAS(S_IWUSR | S_IRUGO, adis16209_read_14bit_signed, adis16209_write_16bit, ADIS16209_XACCL_NULL); -static IIO_DEV_ATTR_ACCEL_Y_OFFSET(S_IWUSR | S_IRUGO, +static IIO_DEV_ATTR_ACCEL_Y_CALIBBIAS(S_IWUSR | S_IRUGO, adis16209_read_14bit_signed, adis16209_write_16bit, ADIS16209_YACCL_NULL); -static IIO_CONST_ATTR(accel_scale, "0.24414"); +static IIO_CONST_ATTR_ACCEL_SCALE("0.002394195531"); static IIO_DEV_ATTR_INCLI_X(adis16209_read_14bit_signed, ADIS16209_XINCL_OUT); static IIO_DEV_ATTR_INCLI_Y(adis16209_read_14bit_signed, ADIS16209_YINCL_OUT); -static IIO_DEV_ATTR_INCLI_X_OFFSET(S_IWUSR | S_IRUGO, - adis16209_read_14bit_signed, - adis16209_write_16bit, - ADIS16209_XACCL_NULL); -static IIO_DEV_ATTR_INCLI_Y_OFFSET(S_IWUSR | S_IRUGO, - adis16209_read_14bit_signed, - adis16209_write_16bit, - ADIS16209_YACCL_NULL); -static IIO_CONST_ATTR(incli_scale, "0.025"); +static IIO_CONST_ATTR(incli_scale, "0.00043633231"); static IIO_DEVICE_ATTR(rot_raw, S_IRUGO, adis16209_read_14bit_signed, NULL, ADIS16209_ROT_OUT); -static IIO_DEV_ATTR_TEMP(adis16209_read_temp); -static IIO_CONST_ATTR(temp_offset, "25"); -static IIO_CONST_ATTR(temp_scale, "-0.47"); +static IIO_DEV_ATTR_TEMP_RAW(adis16209_read_temp); +static IIO_CONST_ATTR_TEMP_OFFSET("25"); +static IIO_CONST_ATTR_TEMP_SCALE("-0.47"); static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16209_write_reset, 0); -static IIO_CONST_ATTR(name, "adis16209"); +static IIO_CONST_ATTR_NAME("adis16209"); static struct attribute *adis16209_event_attributes[] = { NULL @@ -443,24 +438,22 @@ static struct attribute_group adis16209_event_attribute_group = { }; static struct attribute *adis16209_attributes[] = { - &iio_dev_attr_in_supply_raw.dev_attr.attr, - &iio_const_attr_in_supply_scale.dev_attr.attr, - &iio_dev_attr_temp.dev_attr.attr, + &iio_dev_attr_in0_supply_raw.dev_attr.attr, + &iio_const_attr_in0_supply_scale.dev_attr.attr, + &iio_dev_attr_temp_raw.dev_attr.attr, &iio_const_attr_temp_offset.dev_attr.attr, &iio_const_attr_temp_scale.dev_attr.attr, &iio_dev_attr_reset.dev_attr.attr, &iio_const_attr_name.dev_attr.attr, - &iio_dev_attr_in0_raw.dev_attr.attr, - &iio_const_attr_in0_scale.dev_attr.attr, + &iio_dev_attr_in1_raw.dev_attr.attr, + &iio_const_attr_in1_scale.dev_attr.attr, &iio_dev_attr_accel_x_raw.dev_attr.attr, &iio_dev_attr_accel_y_raw.dev_attr.attr, - &iio_dev_attr_accel_x_offset.dev_attr.attr, - &iio_dev_attr_accel_y_offset.dev_attr.attr, + &iio_dev_attr_accel_x_calibbias.dev_attr.attr, + &iio_dev_attr_accel_y_calibbias.dev_attr.attr, &iio_const_attr_accel_scale.dev_attr.attr, &iio_dev_attr_incli_x_raw.dev_attr.attr, &iio_dev_attr_incli_y_raw.dev_attr.attr, - &iio_dev_attr_incli_x_offset.dev_attr.attr, - &iio_dev_attr_incli_y_offset.dev_attr.attr, &iio_const_attr_incli_scale.dev_attr.attr, &iio_dev_attr_rot_raw.dev_attr.attr, NULL @@ -518,7 +511,7 @@ static int __devinit adis16209_probe(struct spi_device *spi) goto error_unreg_ring_funcs; regdone = 1; - ret = adis16209_initialize_ring(st->indio_dev->ring); + ret = iio_ring_buffer_register(st->indio_dev->ring, 0); if (ret) { printk(KERN_ERR "failed to initialize the ring\n"); goto error_unreg_ring_funcs; @@ -550,7 +543,7 @@ error_unregister_line: if (spi->irq) iio_unregister_interrupt_line(st->indio_dev, 0); error_uninitialize_ring: - adis16209_uninitialize_ring(st->indio_dev->ring); + iio_ring_buffer_unregister(st->indio_dev->ring); error_unreg_ring_funcs: adis16209_unconfigure_ring(st->indio_dev); error_free_dev: @@ -579,7 +572,7 @@ static int adis16209_remove(struct spi_device *spi) if (spi->irq) iio_unregister_interrupt_line(indio_dev, 0); - adis16209_uninitialize_ring(indio_dev->ring); + iio_ring_buffer_unregister(indio_dev->ring); iio_device_unregister(indio_dev); adis16209_unconfigure_ring(indio_dev); kfree(st->tx); diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c index 533e28574910..033135c6f226 100644 --- a/drivers/staging/iio/accel/adis16209_ring.c +++ b/drivers/staging/iio/accel/adis16209_ring.c @@ -6,6 +6,7 @@ #include <linux/device.h> #include <linux/kernel.h> #include <linux/spi/spi.h> +#include <linux/slab.h> #include <linux/sysfs.h> #include <linux/list.h> @@ -16,45 +17,52 @@ #include "../trigger.h" #include "adis16209.h" -/** - * combine_8_to_16() utility function to munge to u8s into u16 - **/ -static inline u16 combine_8_to_16(u8 lower, u8 upper) -{ - u16 _lower = lower; - u16 _upper = upper; - return _lower | (_upper << 8); -} - -static IIO_SCAN_EL_C(supply, ADIS16209_SCAN_SUPPLY, IIO_UNSIGNED(14), +static IIO_SCAN_EL_C(in_supply, ADIS16209_SCAN_SUPPLY, ADIS16209_SUPPLY_OUT, NULL); -static IIO_SCAN_EL_C(accel_x, ADIS16209_SCAN_ACC_X, IIO_SIGNED(14), - ADIS16209_XACCL_OUT, NULL); -static IIO_SCAN_EL_C(accel_y, ADIS16209_SCAN_ACC_Y, IIO_SIGNED(14), - ADIS16209_YACCL_OUT, NULL); -static IIO_SCAN_EL_C(aux_adc, ADIS16209_SCAN_AUX_ADC, IIO_UNSIGNED(12), - ADIS16209_AUX_ADC, NULL); -static IIO_SCAN_EL_C(temp, ADIS16209_SCAN_TEMP, IIO_UNSIGNED(12), - ADIS16209_TEMP_OUT, NULL); -static IIO_SCAN_EL_C(incli_x, ADIS16209_SCAN_INCLI_X, IIO_SIGNED(14), +static IIO_CONST_ATTR_SCAN_EL_TYPE(in_supply, u, 14, 16) +static IIO_SCAN_EL_C(accel_x, ADIS16209_SCAN_ACC_X, ADIS16209_XACCL_OUT, NULL); +static IIO_SCAN_EL_C(accel_y, ADIS16209_SCAN_ACC_Y, ADIS16209_YACCL_OUT, NULL); +static IIO_CONST_ATTR_SCAN_EL_TYPE(accel, s, 14, 16); +static IIO_SCAN_EL_C(in0, ADIS16209_SCAN_AUX_ADC, ADIS16209_AUX_ADC, NULL); +static IIO_CONST_ATTR_SCAN_EL_TYPE(in0, u, 12, 16); +static IIO_SCAN_EL_C(temp, ADIS16209_SCAN_TEMP, ADIS16209_TEMP_OUT, NULL); +static IIO_CONST_ATTR_SCAN_EL_TYPE(temp, u, 12, 16); +static IIO_SCAN_EL_C(incli_x, ADIS16209_SCAN_INCLI_X, ADIS16209_XINCL_OUT, NULL); -static IIO_SCAN_EL_C(incli_y, ADIS16209_SCAN_INCLI_Y, IIO_SIGNED(14), +static IIO_SCAN_EL_C(incli_y, ADIS16209_SCAN_INCLI_Y, ADIS16209_YINCL_OUT, NULL); -static IIO_SCAN_EL_C(rot, ADIS16209_SCAN_ROT, IIO_SIGNED(14), - ADIS16209_ROT_OUT, NULL); - +static IIO_CONST_ATTR_SCAN_EL_TYPE(incli, s, 14, 16); +static IIO_SCAN_EL_C(rot, ADIS16209_SCAN_ROT, ADIS16209_ROT_OUT, NULL); +static IIO_CONST_ATTR_SCAN_EL_TYPE(rot, s, 14, 16); static IIO_SCAN_EL_TIMESTAMP(8); +static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64); static struct attribute *adis16209_scan_el_attrs[] = { - &iio_scan_el_supply.dev_attr.attr, + &iio_scan_el_in_supply.dev_attr.attr, + &iio_const_attr_in_supply_index.dev_attr.attr, + &iio_const_attr_in_supply_type.dev_attr.attr, &iio_scan_el_accel_x.dev_attr.attr, + &iio_const_attr_accel_x_index.dev_attr.attr, &iio_scan_el_accel_y.dev_attr.attr, - &iio_scan_el_aux_adc.dev_attr.attr, + &iio_const_attr_accel_y_index.dev_attr.attr, + &iio_const_attr_accel_type.dev_attr.attr, + &iio_scan_el_in0.dev_attr.attr, + &iio_const_attr_in0_index.dev_attr.attr, + &iio_const_attr_in0_type.dev_attr.attr, &iio_scan_el_temp.dev_attr.attr, + &iio_const_attr_temp_index.dev_attr.attr, + &iio_const_attr_temp_type.dev_attr.attr, &iio_scan_el_incli_x.dev_attr.attr, + &iio_const_attr_incli_x_index.dev_attr.attr, &iio_scan_el_incli_y.dev_attr.attr, + &iio_const_attr_incli_y_index.dev_attr.attr, + &iio_const_attr_incli_type.dev_attr.attr, &iio_scan_el_rot.dev_attr.attr, + &iio_const_attr_rot_index.dev_attr.attr, + &iio_const_attr_rot_type.dev_attr.attr, &iio_scan_el_timestamp.dev_attr.attr, + &iio_const_attr_timestamp_index.dev_attr.attr, + &iio_const_attr_timestamp_type.dev_attr.attr, NULL, }; @@ -67,10 +75,10 @@ static struct attribute_group adis16209_scan_el_group = { * adis16209_poll_func_th() top half interrupt handler called by trigger * @private_data: iio_dev **/ -static void adis16209_poll_func_th(struct iio_dev *indio_dev) +static void adis16209_poll_func_th(struct iio_dev *indio_dev, s64 time) { struct adis16209_state *st = iio_dev_get_devdata(indio_dev); - st->last_timestamp = indio_dev->trig->timestamp; + st->last_timestamp = time; schedule_work(&st->work_trigger_to_ring); } @@ -124,11 +132,11 @@ static void adis16209_trigger_bh_to_ring(struct work_struct *work_s) struct adis16209_state *st = container_of(work_s, struct adis16209_state, work_trigger_to_ring); + struct iio_ring_buffer *ring = st->indio_dev->ring; int i = 0; s16 *data; - size_t datasize = st->indio_dev - ->ring->access.get_bpd(st->indio_dev->ring); + size_t datasize = ring->access.get_bytes_per_datum(ring); data = kmalloc(datasize , GFP_KERNEL); if (data == NULL) { @@ -136,20 +144,19 @@ static void adis16209_trigger_bh_to_ring(struct work_struct *work_s) return; } - if (st->indio_dev->scan_count) + if (ring->scan_count) if (adis16209_read_ring_data(&st->indio_dev->dev, st->rx) >= 0) - for (; i < st->indio_dev->scan_count; i++) { - data[i] = combine_8_to_16(st->rx[i*2+1], - st->rx[i*2]); - } + for (; i < ring->scan_count; i++) + data[i] = be16_to_cpup( + (__be16 *)&(st->rx[i*2])); /* Guaranteed to be aligned with 8 byte boundary */ - if (st->indio_dev->scan_timestamp) + if (ring->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp; - st->indio_dev->ring->access.store_to(st->indio_dev->ring, - (u8 *)data, - st->last_timestamp); + ring->access.store_to(ring, + (u8 *)data, + st->last_timestamp); iio_trigger_notify_done(st->indio_dev->trig); kfree(data); @@ -157,50 +164,6 @@ static void adis16209_trigger_bh_to_ring(struct work_struct *work_s) return; } -/* in these circumstances is it better to go with unaligned packing and - * deal with the cost?*/ -static int adis16209_data_rdy_ring_preenable(struct iio_dev *indio_dev) -{ - size_t size; - dev_dbg(&indio_dev->dev, "%s\n", __func__); - /* Check if there are any scan elements enabled, if not fail*/ - if (!(indio_dev->scan_count || indio_dev->scan_timestamp)) - return -EINVAL; - - if (indio_dev->ring->access.set_bpd) { - if (indio_dev->scan_timestamp) - if (indio_dev->scan_count) - /* Timestamp (aligned to s64) and data */ - size = (((indio_dev->scan_count * sizeof(s16)) - + sizeof(s64) - 1) - & ~(sizeof(s64) - 1)) - + sizeof(s64); - else /* Timestamp only */ - size = sizeof(s64); - else /* Data only */ - size = indio_dev->scan_count*sizeof(s16); - indio_dev->ring->access.set_bpd(indio_dev->ring, size); - } - - return 0; -} - -static int adis16209_data_rdy_ring_postenable(struct iio_dev *indio_dev) -{ - return indio_dev->trig - ? iio_trigger_attach_poll_func(indio_dev->trig, - indio_dev->pollfunc) - : 0; -} - -static int adis16209_data_rdy_ring_predisable(struct iio_dev *indio_dev) -{ - return indio_dev->trig - ? iio_trigger_dettach_poll_func(indio_dev->trig, - indio_dev->pollfunc) - : 0; -} - void adis16209_unconfigure_ring(struct iio_dev *indio_dev) { kfree(indio_dev->pollfunc); @@ -213,19 +176,6 @@ int adis16209_configure_ring(struct iio_dev *indio_dev) struct adis16209_state *st = indio_dev->dev_data; struct iio_ring_buffer *ring; INIT_WORK(&st->work_trigger_to_ring, adis16209_trigger_bh_to_ring); - /* Set default scan mode */ - - iio_scan_mask_set(indio_dev, iio_scan_el_supply.number); - iio_scan_mask_set(indio_dev, iio_scan_el_rot.number); - iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number); - iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number); - iio_scan_mask_set(indio_dev, iio_scan_el_temp.number); - iio_scan_mask_set(indio_dev, iio_scan_el_aux_adc.number); - iio_scan_mask_set(indio_dev, iio_scan_el_incli_x.number); - iio_scan_mask_set(indio_dev, iio_scan_el_incli_y.number); - indio_dev->scan_timestamp = true; - - indio_dev->scan_el_attrs = &adis16209_scan_el_group; ring = iio_sw_rb_allocate(indio_dev); if (!ring) { @@ -235,18 +185,28 @@ int adis16209_configure_ring(struct iio_dev *indio_dev) indio_dev->ring = ring; /* Effectively select the ring buffer implementation */ iio_ring_sw_register_funcs(&ring->access); - ring->preenable = &adis16209_data_rdy_ring_preenable; - ring->postenable = &adis16209_data_rdy_ring_postenable; - ring->predisable = &adis16209_data_rdy_ring_predisable; + ring->bpe = 2; + ring->scan_el_attrs = &adis16209_scan_el_group; + ring->scan_timestamp = true; + ring->preenable = &iio_sw_ring_preenable; + ring->postenable = &iio_triggered_ring_postenable; + ring->predisable = &iio_triggered_ring_predisable; ring->owner = THIS_MODULE; - indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL); - if (indio_dev->pollfunc == NULL) { - ret = -ENOMEM; - goto error_iio_sw_rb_free;; - } - indio_dev->pollfunc->poll_func_main = &adis16209_poll_func_th; - indio_dev->pollfunc->private_data = indio_dev; + /* Set default scan mode */ + iio_scan_mask_set(ring, iio_scan_el_in_supply.number); + iio_scan_mask_set(ring, iio_scan_el_rot.number); + iio_scan_mask_set(ring, iio_scan_el_accel_x.number); + iio_scan_mask_set(ring, iio_scan_el_accel_y.number); + iio_scan_mask_set(ring, iio_scan_el_temp.number); + iio_scan_mask_set(ring, iio_scan_el_in0.number); + iio_scan_mask_set(ring, iio_scan_el_incli_x.number); + iio_scan_mask_set(ring, iio_scan_el_incli_y.number); + + ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16209_poll_func_th); + if (ret) + goto error_iio_sw_rb_free; + indio_dev->modes |= INDIO_RING_TRIGGERED; return 0; @@ -254,13 +214,3 @@ error_iio_sw_rb_free: iio_sw_rb_free(indio_dev->ring); return ret; } - -int adis16209_initialize_ring(struct iio_ring_buffer *ring) -{ - return iio_ring_buffer_register(ring, 0); -} - -void adis16209_uninitialize_ring(struct iio_ring_buffer *ring) -{ - iio_ring_buffer_unregister(ring); -} diff --git a/drivers/staging/iio/accel/adis16209_trigger.c b/drivers/staging/iio/accel/adis16209_trigger.c index 4a0507c9a13b..d2980dc74440 100644 --- a/drivers/staging/iio/accel/adis16209_trigger.c +++ b/drivers/staging/iio/accel/adis16209_trigger.c @@ -23,15 +23,14 @@ static int adis16209_data_rdy_trig_poll(struct iio_dev *dev_info, struct adis16209_state *st = iio_dev_get_devdata(dev_info); struct iio_trigger *trig = st->trig; - trig->timestamp = timestamp; - iio_trigger_poll(trig); + iio_trigger_poll(trig, timestamp); return IRQ_HANDLED; } IIO_EVENT_SH(data_rdy_trig, &adis16209_data_rdy_trig_poll); -static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL); +static IIO_TRIGGER_NAME_ATTR; static struct attribute *adis16209_trigger_attrs[] = { &dev_attr_name.attr, @@ -83,14 +82,13 @@ int adis16209_probe_trigger(struct iio_dev *indio_dev) struct adis16209_state *st = indio_dev->dev_data; st->trig = iio_allocate_trigger(); - st->trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH, GFP_KERNEL); + st->trig->name = kasprintf(GFP_KERNEL, + "adis16209-dev%d", + indio_dev->id); if (!st->trig->name) { ret = -ENOMEM; goto error_free_trig; } - snprintf((char *)st->trig->name, - IIO_TRIGGER_NAME_LENGTH, - "adis16209-dev%d", indio_dev->id); st->trig->dev.parent = &st->us->dev; st->trig->owner = THIS_MODULE; st->trig->private_data = st; diff --git a/drivers/staging/iio/accel/adis16220.h b/drivers/staging/iio/accel/adis16220.h index 2abf4850b373..7013314a9d77 100644 --- a/drivers/staging/iio/accel/adis16220.h +++ b/drivers/staging/iio/accel/adis16220.h @@ -127,7 +127,6 @@ * struct adis16220_state - device instance specific data * @us: actual spi_device * @work_trigger_to_ring: bh for triggered event handling - * @work_cont_thresh: CLEAN * @inter: used to check if new interrupt has been triggered * @last_timestamp: passing timestamp from th to bh of interrupt handler * @indio_dev: industrial I/O device structure diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c index 6de439fd1675..c86d1498737d 100644 --- a/drivers/staging/iio/accel/adis16220_core.c +++ b/drivers/staging/iio/accel/adis16220_core.c @@ -14,7 +14,7 @@ #include <linux/device.h> #include <linux/kernel.h> #include <linux/spi/spi.h> - +#include <linux/slab.h> #include <linux/sysfs.h> #include <linux/list.h> @@ -72,13 +72,13 @@ static int adis16220_spi_write_reg_16(struct device *dev, .bits_per_word = 8, .len = 2, .cs_change = 1, - .delay_usecs = 25, + .delay_usecs = 35, }, { .tx_buf = st->tx + 2, .bits_per_word = 8, .len = 2, .cs_change = 1, - .delay_usecs = 25, + .delay_usecs = 35, }, }; @@ -118,13 +118,13 @@ static int adis16220_spi_read_reg_16(struct device *dev, .bits_per_word = 8, .len = 2, .cs_change = 1, - .delay_usecs = 25, + .delay_usecs = 35, }, { .rx_buf = st->rx, .bits_per_word = 8, .len = 2, .cs_change = 1, - .delay_usecs = 25, + .delay_usecs = 35, }, }; @@ -291,9 +291,9 @@ static int adis16220_check_status(struct device *dev) if (status & ADIS16220_DIAG_STAT_FLASH_UPT) dev_err(dev, "Flash update failed\n"); if (status & ADIS16220_DIAG_STAT_POWER_HIGH) - dev_err(dev, "Power supply above 5.25V\n"); + dev_err(dev, "Power supply above 3.625V\n"); if (status & ADIS16220_DIAG_STAT_POWER_LOW) - dev_err(dev, "Power supply below 4.75V\n"); + dev_err(dev, "Power supply below 3.15V\n"); error_ret: return ret; @@ -414,7 +414,7 @@ static ssize_t adis16220_capture_buffer_read(struct adis16220_state *st, return count; } -static ssize_t adis16220_accel_bin_read(struct kobject *kobj, +static ssize_t adis16220_accel_bin_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, @@ -438,7 +438,7 @@ static struct bin_attribute accel_bin = { .size = ADIS16220_CAPTURE_SIZE, }; -static ssize_t adis16220_adc1_bin_read(struct kobject *kobj, +static ssize_t adis16220_adc1_bin_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) @@ -461,7 +461,7 @@ static struct bin_attribute adc1_bin = { .size = ADIS16220_CAPTURE_SIZE, }; -static ssize_t adis16220_adc2_bin_read(struct kobject *kobj, +static ssize_t adis16220_adc2_bin_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) @@ -485,9 +485,9 @@ static struct bin_attribute adc2_bin = { .size = ADIS16220_CAPTURE_SIZE, }; -static IIO_DEV_ATTR_IN_NAMED_RAW(supply, adis16220_read_12bit_unsigned, +static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16220_read_12bit_unsigned, ADIS16220_CAPT_SUPPLY); -static IIO_CONST_ATTR(in_supply_scale, "0.0012207"); +static IIO_CONST_ATTR_IN_NAMED_SCALE(0, supply, "0.0012207"); static IIO_DEV_ATTR_ACCEL(adis16220_read_16bit, ADIS16220_CAPT_BUFA); static IIO_DEVICE_ATTR(accel_peak_raw, S_IRUGO, adis16220_read_16bit, NULL, ADIS16220_CAPT_PEAKA); @@ -495,12 +495,13 @@ static IIO_DEV_ATTR_ACCEL_OFFSET(S_IWUSR | S_IRUGO, adis16220_read_16bit, adis16220_write_16bit, ADIS16220_ACCL_NULL); +static IIO_CONST_ATTR_ACCEL_SCALE("0.18704223545"); static IIO_DEV_ATTR_TEMP_RAW(adis16220_read_12bit_unsigned); -static IIO_CONST_ATTR(temp_offset, "25"); -static IIO_CONST_ATTR(temp_scale, "-0.47"); +static IIO_CONST_ATTR_TEMP_OFFSET("25"); +static IIO_CONST_ATTR_TEMP_SCALE("-0.47"); -static IIO_DEV_ATTR_IN_RAW(0, adis16220_read_16bit, ADIS16220_CAPT_BUF1); -static IIO_DEV_ATTR_IN_RAW(1, adis16220_read_16bit, ADIS16220_CAPT_BUF2); +static IIO_DEV_ATTR_IN_RAW(1, adis16220_read_16bit, ADIS16220_CAPT_BUF1); +static IIO_DEV_ATTR_IN_RAW(2, adis16220_read_16bit, ADIS16220_CAPT_BUF2); static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16220_write_reset, 0); @@ -518,22 +519,23 @@ static IIO_DEV_ATTR_CAPTURE_COUNT(S_IWUSR | S_IRUGO, adis16220_write_16bit, ADIS16220_CAPT_PNTR); -static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("100200"); +static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("100200"); -static IIO_CONST_ATTR(name, "adis16220"); +static IIO_CONST_ATTR_NAME("adis16220"); static struct attribute *adis16220_attributes[] = { - &iio_dev_attr_in_supply_raw.dev_attr.attr, - &iio_const_attr_in_supply_scale.dev_attr.attr, + &iio_dev_attr_in0_supply_raw.dev_attr.attr, + &iio_const_attr_in0_supply_scale.dev_attr.attr, &iio_dev_attr_accel_raw.dev_attr.attr, &iio_dev_attr_accel_offset.dev_attr.attr, &iio_dev_attr_accel_peak_raw.dev_attr.attr, + &iio_const_attr_accel_scale.dev_attr.attr, &iio_dev_attr_temp_raw.dev_attr.attr, - &iio_dev_attr_in0_raw.dev_attr.attr, &iio_dev_attr_in1_raw.dev_attr.attr, + &iio_dev_attr_in2_raw.dev_attr.attr, &iio_const_attr_temp_offset.dev_attr.attr, &iio_const_attr_temp_scale.dev_attr.attr, - &iio_const_attr_available_sampling_frequency.dev_attr.attr, + &iio_const_attr_sampling_frequency_available.dev_attr.attr, &iio_dev_attr_reset.dev_attr.attr, &iio_dev_attr_capture.dev_attr.attr, &iio_dev_attr_capture_count.dev_attr.attr, diff --git a/drivers/staging/iio/accel/adis16240.h b/drivers/staging/iio/accel/adis16240.h index dcff43c75235..51a807dde27c 100644 --- a/drivers/staging/iio/accel/adis16240.h +++ b/drivers/staging/iio/accel/adis16240.h @@ -127,7 +127,6 @@ * struct adis16240_state - device instance specific data * @us: actual spi_device * @work_trigger_to_ring: bh for triggered event handling - * @work_cont_thresh: CLEAN * @inter: used to check if new interrupt has been triggered * @last_timestamp: passing timestamp from th to bh of interrupt handler * @indio_dev: industrial I/O device structure @@ -139,7 +138,6 @@ struct adis16240_state { struct spi_device *us; struct work_struct work_trigger_to_ring; - struct iio_work_cont work_cont_thresh; s64 last_timestamp; struct iio_dev *indio_dev; struct iio_trigger *trig; @@ -155,14 +153,12 @@ int adis16240_set_irq(struct device *dev, bool enable); * filling. This may change! */ -enum adis16240_scan { - ADIS16240_SCAN_SUPPLY, - ADIS16240_SCAN_ACC_X, - ADIS16240_SCAN_ACC_Y, - ADIS16240_SCAN_ACC_Z, - ADIS16240_SCAN_AUX_ADC, - ADIS16240_SCAN_TEMP, -}; +#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_AUX_ADC 4 +#define ADIS16240_SCAN_TEMP 5 void adis16240_remove_trigger(struct iio_dev *indio_dev); int adis16240_probe_trigger(struct iio_dev *indio_dev); @@ -175,8 +171,6 @@ ssize_t adis16240_read_data_from_ring(struct device *dev, int adis16240_configure_ring(struct iio_dev *indio_dev); void adis16240_unconfigure_ring(struct iio_dev *indio_dev); -int adis16240_initialize_ring(struct iio_ring_buffer *ring); -void adis16240_uninitialize_ring(struct iio_ring_buffer *ring); #else /* CONFIG_IIO_RING_BUFFER */ static inline void adis16240_remove_trigger(struct iio_dev *indio_dev) @@ -205,14 +199,5 @@ static inline void adis16240_unconfigure_ring(struct iio_dev *indio_dev) { } -static inline int adis16240_initialize_ring(struct iio_ring_buffer *ring) -{ - return 0; -} - -static inline void adis16240_uninitialize_ring(struct iio_ring_buffer *ring) -{ -} - #endif /* CONFIG_IIO_RING_BUFFER */ #endif /* SPI_ADIS16240_H_ */ diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c index 54fd6d77412f..d11d164207ee 100644 --- a/drivers/staging/iio/accel/adis16240_core.c +++ b/drivers/staging/iio/accel/adis16240_core.c @@ -14,12 +14,13 @@ #include <linux/device.h> #include <linux/kernel.h> #include <linux/spi/spi.h> - +#include <linux/slab.h> #include <linux/sysfs.h> #include <linux/list.h> #include "../iio.h" #include "../sysfs.h" +#include "../ring_generic.h" #include "accel.h" #include "../adc/adc.h" @@ -74,13 +75,13 @@ static int adis16240_spi_write_reg_16(struct device *dev, .bits_per_word = 8, .len = 2, .cs_change = 1, - .delay_usecs = 25, + .delay_usecs = 35, }, { .tx_buf = st->tx + 2, .bits_per_word = 8, .len = 2, .cs_change = 1, - .delay_usecs = 25, + .delay_usecs = 35, }, }; @@ -120,13 +121,13 @@ static int adis16240_spi_read_reg_16(struct device *dev, .bits_per_word = 8, .len = 2, .cs_change = 1, - .delay_usecs = 25, + .delay_usecs = 35, }, { .rx_buf = st->rx, .bits_per_word = 8, .len = 2, .cs_change = 1, - .delay_usecs = 25, + .delay_usecs = 35, }, }; @@ -375,11 +376,14 @@ err_ret: return ret; } -static IIO_DEV_ATTR_IN_NAMED_RAW(supply, adis16240_read_10bit_unsigned, +static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16240_read_10bit_unsigned, ADIS16240_SUPPLY_OUT); -static IIO_DEV_ATTR_IN_RAW(0, adis16240_read_10bit_signed, +static IIO_DEV_ATTR_IN_RAW(1, adis16240_read_10bit_signed, ADIS16240_AUX_ADC); -static IIO_CONST_ATTR(in_supply_scale, "0.00488"); +static IIO_CONST_ATTR_IN_NAMED_SCALE(0, supply, "0.00488"); + +static IIO_CONST_ATTR_ACCEL_SCALE("0.50406181"); +static IIO_CONST_ATTR(accel_peak_scale, "6.6292954"); static IIO_DEV_ATTR_ACCEL_X(adis16240_read_10bit_signed, ADIS16240_XACCL_OUT); static IIO_DEVICE_ATTR(accel_x_peak_raw, S_IRUGO, @@ -399,26 +403,26 @@ static IIO_DEVICE_ATTR(accel_z_peak_raw, S_IRUGO, static IIO_DEVICE_ATTR(accel_xyz_squared_peak_raw, S_IRUGO, adis16240_read_12bit_signed, NULL, ADIS16240_XYZPEAK_OUT); -static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO, +static IIO_DEV_ATTR_ACCEL_X_CALIBBIAS(S_IWUSR | S_IRUGO, adis16240_read_10bit_signed, adis16240_write_16bit, ADIS16240_XACCL_OFF); -static IIO_DEV_ATTR_ACCEL_Y_OFFSET(S_IWUSR | S_IRUGO, +static IIO_DEV_ATTR_ACCEL_Y_CALIBBIAS(S_IWUSR | S_IRUGO, adis16240_read_10bit_signed, adis16240_write_16bit, ADIS16240_YACCL_OFF); -static IIO_DEV_ATTR_ACCEL_Z_OFFSET(S_IWUSR | S_IRUGO, +static IIO_DEV_ATTR_ACCEL_Z_CALIBBIAS(S_IWUSR | S_IRUGO, adis16240_read_10bit_signed, adis16240_write_16bit, ADIS16240_ZACCL_OFF); static IIO_DEV_ATTR_TEMP_RAW(adis16240_read_10bit_unsigned); -static IIO_CONST_ATTR(temp_scale, "0.244"); +static IIO_CONST_ATTR_TEMP_SCALE("0.244"); static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16240_write_reset, 0); -static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("4096"); +static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("4096"); -static IIO_CONST_ATTR(name, "adis16240"); +static IIO_CONST_ATTR_NAME("adis16240"); static struct attribute *adis16240_event_attributes[] = { NULL @@ -429,22 +433,24 @@ static struct attribute_group adis16240_event_attribute_group = { }; static struct attribute *adis16240_attributes[] = { - &iio_dev_attr_in_supply_raw.dev_attr.attr, - &iio_const_attr_in_supply_scale.dev_attr.attr, - &iio_dev_attr_in0_raw.dev_attr.attr, + &iio_dev_attr_in0_supply_raw.dev_attr.attr, + &iio_const_attr_in0_supply_scale.dev_attr.attr, + &iio_dev_attr_in1_raw.dev_attr.attr, + &iio_const_attr_accel_scale.dev_attr.attr, + &iio_const_attr_accel_peak_scale.dev_attr.attr, &iio_dev_attr_accel_x_raw.dev_attr.attr, - &iio_dev_attr_accel_x_offset.dev_attr.attr, + &iio_dev_attr_accel_x_calibbias.dev_attr.attr, &iio_dev_attr_accel_x_peak_raw.dev_attr.attr, &iio_dev_attr_accel_y_raw.dev_attr.attr, - &iio_dev_attr_accel_y_offset.dev_attr.attr, + &iio_dev_attr_accel_y_calibbias.dev_attr.attr, &iio_dev_attr_accel_y_peak_raw.dev_attr.attr, &iio_dev_attr_accel_z_raw.dev_attr.attr, - &iio_dev_attr_accel_z_offset.dev_attr.attr, + &iio_dev_attr_accel_z_calibbias.dev_attr.attr, &iio_dev_attr_accel_z_peak_raw.dev_attr.attr, &iio_dev_attr_accel_xyz_squared_peak_raw.dev_attr.attr, &iio_dev_attr_temp_raw.dev_attr.attr, &iio_const_attr_temp_scale.dev_attr.attr, - &iio_const_attr_available_sampling_frequency.dev_attr.attr, + &iio_const_attr_sampling_frequency_available.dev_attr.attr, &iio_dev_attr_reset.dev_attr.attr, &iio_const_attr_name.dev_attr.attr, NULL @@ -502,7 +508,7 @@ static int __devinit adis16240_probe(struct spi_device *spi) goto error_unreg_ring_funcs; regdone = 1; - ret = adis16240_initialize_ring(st->indio_dev->ring); + ret = iio_ring_buffer_register(st->indio_dev->ring, 0); if (ret) { printk(KERN_ERR "failed to initialize the ring\n"); goto error_unreg_ring_funcs; @@ -534,7 +540,7 @@ error_unregister_line: if (spi->irq) iio_unregister_interrupt_line(st->indio_dev, 0); error_uninitialize_ring: - adis16240_uninitialize_ring(st->indio_dev->ring); + iio_ring_buffer_unregister(st->indio_dev->ring); error_unreg_ring_funcs: adis16240_unconfigure_ring(st->indio_dev); error_free_dev: @@ -563,7 +569,7 @@ static int adis16240_remove(struct spi_device *spi) if (spi->irq) iio_unregister_interrupt_line(indio_dev, 0); - adis16240_uninitialize_ring(indio_dev->ring); + iio_ring_buffer_unregister(indio_dev->ring); iio_device_unregister(indio_dev); adis16240_unconfigure_ring(indio_dev); kfree(st->tx); diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c index 26b677bd84c0..f882e9c150e2 100644 --- a/drivers/staging/iio/accel/adis16240_ring.c +++ b/drivers/staging/iio/accel/adis16240_ring.c @@ -6,6 +6,7 @@ #include <linux/device.h> #include <linux/kernel.h> #include <linux/spi/spi.h> +#include <linux/slab.h> #include <linux/sysfs.h> #include <linux/list.h> @@ -16,39 +17,40 @@ #include "../trigger.h" #include "adis16240.h" -/** - * combine_8_to_16() utility function to munge to u8s into u16 - **/ -static inline u16 combine_8_to_16(u8 lower, u8 upper) -{ - u16 _lower = lower; - u16 _upper = upper; - return _lower | (_upper << 8); -} - -static IIO_SCAN_EL_C(supply, ADIS16240_SCAN_SUPPLY, IIO_UNSIGNED(10), +static IIO_SCAN_EL_C(in_supply, ADIS16240_SCAN_SUPPLY, ADIS16240_SUPPLY_OUT, NULL); -static IIO_SCAN_EL_C(accel_x, ADIS16240_SCAN_ACC_X, IIO_SIGNED(10), - ADIS16240_XACCL_OUT, NULL); -static IIO_SCAN_EL_C(accel_y, ADIS16240_SCAN_ACC_Y, IIO_SIGNED(10), - ADIS16240_YACCL_OUT, NULL); -static IIO_SCAN_EL_C(accel_z, ADIS16240_SCAN_ACC_Z, IIO_SIGNED(10), - ADIS16240_ZACCL_OUT, NULL); -static IIO_SCAN_EL_C(aux_adc, ADIS16240_SCAN_AUX_ADC, IIO_UNSIGNED(10), - ADIS16240_AUX_ADC, NULL); -static IIO_SCAN_EL_C(temp, ADIS16240_SCAN_TEMP, IIO_UNSIGNED(10), - ADIS16240_TEMP_OUT, NULL); - +static IIO_CONST_ATTR_SCAN_EL_TYPE(in_supply, u, 10, 16); +static IIO_SCAN_EL_C(accel_x, ADIS16240_SCAN_ACC_X, ADIS16240_XACCL_OUT, NULL); +static IIO_SCAN_EL_C(accel_y, ADIS16240_SCAN_ACC_Y, ADIS16240_YACCL_OUT, NULL); +static IIO_SCAN_EL_C(accel_z, ADIS16240_SCAN_ACC_Z, ADIS16240_ZACCL_OUT, NULL); +static IIO_CONST_ATTR_SCAN_EL_TYPE(accel, s, 10, 16); +static IIO_SCAN_EL_C(in0, ADIS16240_SCAN_AUX_ADC, ADIS16240_AUX_ADC, NULL); +static IIO_CONST_ATTR_SCAN_EL_TYPE(in0, u, 10, 16); +static IIO_SCAN_EL_C(temp, ADIS16240_SCAN_TEMP, ADIS16240_TEMP_OUT, NULL); +static IIO_CONST_ATTR_SCAN_EL_TYPE(temp, u, 10, 16); static IIO_SCAN_EL_TIMESTAMP(6); +static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64); static struct attribute *adis16240_scan_el_attrs[] = { - &iio_scan_el_supply.dev_attr.attr, + &iio_scan_el_in_supply.dev_attr.attr, + &iio_const_attr_in_supply_index.dev_attr.attr, + &iio_const_attr_in_supply_type.dev_attr.attr, &iio_scan_el_accel_x.dev_attr.attr, + &iio_const_attr_accel_x_index.dev_attr.attr, &iio_scan_el_accel_y.dev_attr.attr, + &iio_const_attr_accel_y_index.dev_attr.attr, &iio_scan_el_accel_z.dev_attr.attr, - &iio_scan_el_aux_adc.dev_attr.attr, + &iio_const_attr_accel_z_index.dev_attr.attr, + &iio_const_attr_accel_type.dev_attr.attr, + &iio_scan_el_in0.dev_attr.attr, + &iio_const_attr_in0_index.dev_attr.attr, + &iio_const_attr_in0_type.dev_attr.attr, &iio_scan_el_temp.dev_attr.attr, + &iio_const_attr_temp_index.dev_attr.attr, + &iio_const_attr_temp_type.dev_attr.attr, &iio_scan_el_timestamp.dev_attr.attr, + &iio_const_attr_timestamp_index.dev_attr.attr, + &iio_const_attr_timestamp_type.dev_attr.attr, NULL, }; @@ -61,10 +63,10 @@ static struct attribute_group adis16240_scan_el_group = { * adis16240_poll_func_th() top half interrupt handler called by trigger * @private_data: iio_dev **/ -static void adis16240_poll_func_th(struct iio_dev *indio_dev) +static void adis16240_poll_func_th(struct iio_dev *indio_dev, s64 time) { struct adis16240_state *st = iio_dev_get_devdata(indio_dev); - st->last_timestamp = indio_dev->trig->timestamp; + st->last_timestamp = time; schedule_work(&st->work_trigger_to_ring); } @@ -116,11 +118,11 @@ static void adis16240_trigger_bh_to_ring(struct work_struct *work_s) struct adis16240_state *st = container_of(work_s, struct adis16240_state, work_trigger_to_ring); + struct iio_ring_buffer *ring = st->indio_dev->ring; int i = 0; s16 *data; - size_t datasize = st->indio_dev - ->ring->access.get_bpd(st->indio_dev->ring); + size_t datasize = ring->access.get_bytes_per_datum(ring); data = kmalloc(datasize , GFP_KERNEL); if (data == NULL) { @@ -128,18 +130,17 @@ static void adis16240_trigger_bh_to_ring(struct work_struct *work_s) return; } - if (st->indio_dev->scan_count) + if (ring->scan_count) if (adis16240_read_ring_data(&st->indio_dev->dev, st->rx) >= 0) - for (; i < st->indio_dev->scan_count; i++) { - data[i] = combine_8_to_16(st->rx[i*2+1], - st->rx[i*2]); - } + for (; i < ring->scan_count; i++) + data[i] = be16_to_cpup( + (__be16 *)&(st->rx[i*2])); /* Guaranteed to be aligned with 8 byte boundary */ - if (st->indio_dev->scan_timestamp) + if (ring->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp; - st->indio_dev->ring->access.store_to(st->indio_dev->ring, + ring->access.store_to(ring, (u8 *)data, st->last_timestamp); @@ -149,48 +150,6 @@ static void adis16240_trigger_bh_to_ring(struct work_struct *work_s) return; } -static int adis16240_data_rdy_ring_preenable(struct iio_dev *indio_dev) -{ - size_t size; - dev_dbg(&indio_dev->dev, "%s\n", __func__); - /* Check if there are any scan elements enabled, if not fail*/ - if (!(indio_dev->scan_count || indio_dev->scan_timestamp)) - return -EINVAL; - - if (indio_dev->ring->access.set_bpd) { - if (indio_dev->scan_timestamp) - if (indio_dev->scan_count) - /* Timestamp (aligned sizeof(s64) and data */ - size = (((indio_dev->scan_count * sizeof(s16)) - + sizeof(s64) - 1) - & ~(sizeof(s64) - 1)) - + sizeof(s64); - else /* Timestamp only */ - size = sizeof(s64); - else /* Data only */ - size = indio_dev->scan_count*sizeof(s16); - indio_dev->ring->access.set_bpd(indio_dev->ring, size); - } - - return 0; -} - -static int adis16240_data_rdy_ring_postenable(struct iio_dev *indio_dev) -{ - return indio_dev->trig - ? iio_trigger_attach_poll_func(indio_dev->trig, - indio_dev->pollfunc) - : 0; -} - -static int adis16240_data_rdy_ring_predisable(struct iio_dev *indio_dev) -{ - return indio_dev->trig - ? iio_trigger_dettach_poll_func(indio_dev->trig, - indio_dev->pollfunc) - : 0; -} - void adis16240_unconfigure_ring(struct iio_dev *indio_dev) { kfree(indio_dev->pollfunc); @@ -203,17 +162,6 @@ int adis16240_configure_ring(struct iio_dev *indio_dev) struct adis16240_state *st = indio_dev->dev_data; struct iio_ring_buffer *ring; INIT_WORK(&st->work_trigger_to_ring, adis16240_trigger_bh_to_ring); - /* Set default scan mode */ - - iio_scan_mask_set(indio_dev, iio_scan_el_supply.number); - iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number); - iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number); - iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number); - iio_scan_mask_set(indio_dev, iio_scan_el_temp.number); - iio_scan_mask_set(indio_dev, iio_scan_el_aux_adc.number); - indio_dev->scan_timestamp = true; - - indio_dev->scan_el_attrs = &adis16240_scan_el_group; ring = iio_sw_rb_allocate(indio_dev); if (!ring) { @@ -223,18 +171,26 @@ int adis16240_configure_ring(struct iio_dev *indio_dev) indio_dev->ring = ring; /* Effectively select the ring buffer implementation */ iio_ring_sw_register_funcs(&ring->access); - ring->preenable = &adis16240_data_rdy_ring_preenable; - ring->postenable = &adis16240_data_rdy_ring_postenable; - ring->predisable = &adis16240_data_rdy_ring_predisable; + ring->bpe = 2; + ring->scan_el_attrs = &adis16240_scan_el_group; + ring->scan_timestamp = true; + ring->preenable = &iio_sw_ring_preenable; + ring->postenable = &iio_triggered_ring_postenable; + ring->predisable = &iio_triggered_ring_predisable; ring->owner = THIS_MODULE; - indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL); - if (indio_dev->pollfunc == NULL) { - ret = -ENOMEM; - goto error_iio_sw_rb_free;; - } - indio_dev->pollfunc->poll_func_main = &adis16240_poll_func_th; - indio_dev->pollfunc->private_data = indio_dev; + /* Set default scan mode */ + iio_scan_mask_set(ring, iio_scan_el_in_supply.number); + iio_scan_mask_set(ring, iio_scan_el_accel_x.number); + iio_scan_mask_set(ring, iio_scan_el_accel_y.number); + iio_scan_mask_set(ring, iio_scan_el_accel_z.number); + iio_scan_mask_set(ring, iio_scan_el_temp.number); + iio_scan_mask_set(ring, iio_scan_el_in0.number); + + ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16240_poll_func_th); + if (ret) + goto error_iio_sw_rb_free; + indio_dev->modes |= INDIO_RING_TRIGGERED; return 0; @@ -243,12 +199,3 @@ error_iio_sw_rb_free: return ret; } -int adis16240_initialize_ring(struct iio_ring_buffer *ring) -{ - return iio_ring_buffer_register(ring, 0); -} - -void adis16240_uninitialize_ring(struct iio_ring_buffer *ring) -{ - iio_ring_buffer_unregister(ring); -} diff --git a/drivers/staging/iio/accel/adis16240_trigger.c b/drivers/staging/iio/accel/adis16240_trigger.c index df1312e17f4b..6cb8681f2853 100644 --- a/drivers/staging/iio/accel/adis16240_trigger.c +++ b/drivers/staging/iio/accel/adis16240_trigger.c @@ -23,15 +23,14 @@ static int adis16240_data_rdy_trig_poll(struct iio_dev *dev_info, struct adis16240_state *st = iio_dev_get_devdata(dev_info); struct iio_trigger *trig = st->trig; - trig->timestamp = timestamp; - iio_trigger_poll(trig); + iio_trigger_poll(trig, timestamp); return IRQ_HANDLED; } IIO_EVENT_SH(data_rdy_trig, &adis16240_data_rdy_trig_poll); -static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL); +static IIO_TRIGGER_NAME_ATTR; static struct attribute *adis16240_trigger_attrs[] = { &dev_attr_name.attr, @@ -83,14 +82,13 @@ int adis16240_probe_trigger(struct iio_dev *indio_dev) struct adis16240_state *st = indio_dev->dev_data; st->trig = iio_allocate_trigger(); - st->trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH, GFP_KERNEL); + st->trig->name = kasprintf(GFP_KERNEL, + "adis16240-dev%d", + indio_dev->id); if (!st->trig->name) { ret = -ENOMEM; goto error_free_trig; } - snprintf((char *)st->trig->name, - IIO_TRIGGER_NAME_LENGTH, - "adis16240-dev%d", indio_dev->id); st->trig->dev.parent = &st->us->dev; st->trig->owner = THIS_MODULE; st->trig->private_data = st; diff --git a/drivers/staging/iio/accel/inclinometer.h b/drivers/staging/iio/accel/inclinometer.h index 5b49f835eac5..faf73d7892e0 100644 --- a/drivers/staging/iio/accel/inclinometer.h +++ b/drivers/staging/iio/accel/inclinometer.h @@ -21,3 +21,5 @@ #define IIO_DEV_ATTR_INCLI_Z_OFFSET(_mode, _show, _store, _addr) \ IIO_DEVICE_ATTR(incli_z_offset, _mode, _show, _store, _addr) +#define IIO_CONST_ATTR_INCLI_SCALE(_string) \ + IIO_CONST_ATTR(incli_scale, _string) diff --git a/drivers/staging/iio/accel/kxsd9.c b/drivers/staging/iio/accel/kxsd9.c index ae7ffe114fc5..79f57950ebeb 100644 --- a/drivers/staging/iio/accel/kxsd9.c +++ b/drivers/staging/iio/accel/kxsd9.c @@ -16,17 +16,11 @@ * heavily optimized ring buffer access function. */ -#include <linux/interrupt.h> -#include <linux/gpio.h> -#include <linux/fs.h> #include <linux/device.h> #include <linux/kernel.h> #include <linux/spi/spi.h> #include <linux/sysfs.h> -#include <linux/rtc.h> -#include <linux/delay.h> #include <linux/slab.h> -#include <linux/string.h> #include "../iio.h" #include "../sysfs.h" diff --git a/drivers/staging/iio/accel/lis3l02dq.h b/drivers/staging/iio/accel/lis3l02dq.h index e76a97937a36..6e730553fca8 100644 --- a/drivers/staging/iio/accel/lis3l02dq.h +++ b/drivers/staging/iio/accel/lis3l02dq.h @@ -148,30 +148,31 @@ Form of high byte dependant on justification set in ctrl reg */ #define LIS3L02DQ_MAX_RX 12 /** * struct lis3l02dq_state - device instance specific data + * @helper: data and func pointer allowing generic functions * @us: actual spi_device - * @work_trigger_to_ring: bh for triggered event handling - * @work_cont_thresh: CLEAN + * @work_thresh: bh for threshold events + * @thresh_timestamp: timestamp for threshold interrupts. * @inter: used to check if new interrupt has been triggered - * @last_timestamp: passing timestamp from th to bh of interrupt handler - * @indio_dev: industrial I/O device structure * @trig: data ready trigger registered with iio * @tx: transmit buffer * @rx: recieve buffer * @buf_lock: mutex to protect tx and rx **/ struct lis3l02dq_state { + struct iio_sw_ring_helper_state help; struct spi_device *us; - struct work_struct work_trigger_to_ring; - struct iio_work_cont work_cont_thresh; + struct work_struct work_thresh; + s64 thresh_timestamp; bool inter; - s64 last_timestamp; - struct iio_dev *indio_dev; struct iio_trigger *trig; u8 *tx; u8 *rx; struct mutex buf_lock; }; +#define lis3l02dq_h_to_s(_h) \ + container_of(_h, struct lis3l02dq_state, help) + int lis3l02dq_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val); @@ -195,15 +196,15 @@ ssize_t lis3l02dq_read_accel_from_ring(struct device *dev, int lis3l02dq_configure_ring(struct iio_dev *indio_dev); void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev); -int lis3l02dq_initialize_ring(struct iio_ring_buffer *ring); -void lis3l02dq_uninitialize_ring(struct iio_ring_buffer *ring); #else /* CONFIG_IIO_RING_BUFFER */ -static inline void lis3l02dq_remove_trigger(struct iio_dev *indio_dev) {}; +static inline void lis3l02dq_remove_trigger(struct iio_dev *indio_dev) +{ +} static inline int lis3l02dq_probe_trigger(struct iio_dev *indio_dev) { return 0; -}; +} static inline ssize_t lis3l02dq_read_accel_from_ring(struct device *dev, @@ -211,18 +212,14 @@ lis3l02dq_read_accel_from_ring(struct device *dev, char *buf) { return 0; -}; +} static int lis3l02dq_configure_ring(struct iio_dev *indio_dev) { return 0; -}; +} static inline void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev) -{}; -static inline int lis3l02dq_initialize_ring(struct iio_ring_buffer *ring) { - return 0; -}; -static inline void lis3l02dq_uninitialize_ring(struct iio_ring_buffer *ring) {}; +} #endif /* CONFIG_IIO_RING_BUFFER */ #endif /* SPI_LIS3L02DQ_H_ */ diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c index 6b5577d7d8de..c4b4ab7e6423 100644 --- a/drivers/staging/iio/accel/lis3l02dq_core.c +++ b/drivers/staging/iio/accel/lis3l02dq_core.c @@ -27,6 +27,9 @@ #include "../iio.h" #include "../sysfs.h" +#include "../ring_generic.h" +#include "../ring_sw.h" + #include "accel.h" #include "lis3l02dq.h" @@ -47,7 +50,9 @@ int lis3l02dq_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val) int ret; struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct lis3l02dq_state *st = iio_dev_get_devdata(indio_dev); + struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev); + struct lis3l02dq_state *st = lis3l02dq_h_to_s(h); + struct spi_transfer xfer = { .tx_buf = st->tx, .rx_buf = st->rx, @@ -82,7 +87,9 @@ int lis3l02dq_spi_write_reg_8(struct device *dev, int ret; struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct lis3l02dq_state *st = iio_dev_get_devdata(indio_dev); + struct iio_sw_ring_helper_state *h + = iio_dev_get_devdata(indio_dev); + struct lis3l02dq_state *st = lis3l02dq_h_to_s(h); struct spi_transfer xfer = { .tx_buf = st->tx, .bits_per_word = 8, @@ -96,7 +103,7 @@ int lis3l02dq_spi_write_reg_8(struct device *dev, spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->us, &msg); + ret = spi_sync(st->us, &msg); mutex_unlock(&st->buf_lock); return ret; @@ -116,7 +123,9 @@ static int lis3l02dq_spi_write_reg_s16(struct device *dev, int ret; struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct lis3l02dq_state *st = iio_dev_get_devdata(indio_dev); + struct iio_sw_ring_helper_state *h + = iio_dev_get_devdata(indio_dev); + struct lis3l02dq_state *st = lis3l02dq_h_to_s(h); struct spi_transfer xfers[] = { { .tx_buf = st->tx, .bits_per_word = 8, @@ -158,7 +167,9 @@ static int lis3l02dq_spi_read_reg_s16(struct device *dev, { struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct lis3l02dq_state *st = iio_dev_get_devdata(indio_dev); + struct iio_sw_ring_helper_state *h + = iio_dev_get_devdata(indio_dev); + struct lis3l02dq_state *st = lis3l02dq_h_to_s(h); int ret; struct spi_transfer xfers[] = { { .tx_buf = st->tx, @@ -411,7 +422,7 @@ static int lis3l02dq_initial_setup(struct lis3l02dq_state *st) val = LIS3L02DQ_DEFAULT_CTRL1; /* Write suitable defaults to ctrl1 */ - ret = lis3l02dq_spi_write_reg_8(&st->indio_dev->dev, + ret = lis3l02dq_spi_write_reg_8(&st->help.indio_dev->dev, LIS3L02DQ_REG_CTRL_1_ADDR, &val); if (ret) { @@ -419,7 +430,7 @@ static int lis3l02dq_initial_setup(struct lis3l02dq_state *st) goto err_ret; } /* Repeat as sometimes doesn't work first time?*/ - ret = lis3l02dq_spi_write_reg_8(&st->indio_dev->dev, + ret = lis3l02dq_spi_write_reg_8(&st->help.indio_dev->dev, LIS3L02DQ_REG_CTRL_1_ADDR, &val); if (ret) { @@ -429,17 +440,17 @@ static int lis3l02dq_initial_setup(struct lis3l02dq_state *st) /* Read back to check this has worked acts as loose test of correct * chip */ - ret = lis3l02dq_spi_read_reg_8(&st->indio_dev->dev, + ret = lis3l02dq_spi_read_reg_8(&st->help.indio_dev->dev, LIS3L02DQ_REG_CTRL_1_ADDR, &valtest); if (ret || (valtest != val)) { - dev_err(&st->indio_dev->dev, "device not playing ball"); + dev_err(&st->help.indio_dev->dev, "device not playing ball"); ret = -EINVAL; goto err_ret; } val = LIS3L02DQ_DEFAULT_CTRL2; - ret = lis3l02dq_spi_write_reg_8(&st->indio_dev->dev, + ret = lis3l02dq_spi_write_reg_8(&st->help.indio_dev->dev, LIS3L02DQ_REG_CTRL_2_ADDR, &val); if (ret) { @@ -448,7 +459,7 @@ static int lis3l02dq_initial_setup(struct lis3l02dq_state *st) } val = LIS3L02DQ_REG_WAKE_UP_CFG_LATCH_SRC; - ret = lis3l02dq_spi_write_reg_8(&st->indio_dev->dev, + ret = lis3l02dq_spi_write_reg_8(&st->help.indio_dev->dev, LIS3L02DQ_REG_WAKE_UP_CFG_ADDR, &val); if (ret) @@ -486,7 +497,7 @@ static LIS3L02DQ_UNSIGNED_ATTR(accel_y_calibscale, static LIS3L02DQ_UNSIGNED_ATTR(accel_z_calibscale, LIS3L02DQ_REG_GAIN_Z_ADDR); -static IIO_DEVICE_ATTR(accel_mag_either_rising_value, +static IIO_DEVICE_ATTR(accel_raw_mag_value, S_IWUSR | S_IRUGO, lis3l02dq_read_16bit_signed, lis3l02dq_write_16bit_signed, @@ -524,8 +535,7 @@ static ssize_t lis3l02dq_read_interrupt_config(struct device *dev, LIS3L02DQ_REG_WAKE_UP_CFG_ADDR, (u8 *)&val); - return ret ? ret : sprintf(buf, "%d\n", - (val & this_attr->mask) ? 1 : 0);; + return ret ? ret : sprintf(buf, "%d\n", !!(val & this_attr->mask)); } static ssize_t lis3l02dq_write_interrupt_config(struct device *dev, @@ -595,16 +605,18 @@ error_mutex_unlock: } -static int lis3l02dq_thresh_handler_th(struct iio_dev *dev_info, +static int lis3l02dq_thresh_handler_th(struct iio_dev *indio_dev, int index, s64 timestamp, int no_test) { - struct lis3l02dq_state *st = dev_info->dev_data; + struct iio_sw_ring_helper_state *h + = iio_dev_get_devdata(indio_dev); + struct lis3l02dq_state *st = lis3l02dq_h_to_s(h); /* Stash the timestamp somewhere convenient for the bh */ - st->last_timestamp = timestamp; - schedule_work(&st->work_cont_thresh.ws); + st->thresh_timestamp = timestamp; + schedule_work(&st->work_thresh); return 0; } @@ -615,48 +627,73 @@ static int lis3l02dq_thresh_handler_th(struct iio_dev *dev_info, */ static void lis3l02dq_thresh_handler_bh_no_check(struct work_struct *work_s) { - struct iio_work_cont *wc - = container_of(work_s, struct iio_work_cont, ws); - struct lis3l02dq_state *st = wc->st; + struct lis3l02dq_state *st + = container_of(work_s, + struct lis3l02dq_state, work_thresh); + u8 t; - lis3l02dq_spi_read_reg_8(&st->indio_dev->dev, + lis3l02dq_spi_read_reg_8(&st->help.indio_dev->dev, LIS3L02DQ_REG_WAKE_UP_SRC_ADDR, &t); if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_HIGH) - iio_push_event(st->indio_dev, 0, - IIO_EVENT_CODE_ACCEL_Z_HIGH, - st->last_timestamp); + iio_push_event(st->help.indio_dev, 0, + IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL, + 0, + IIO_EV_MOD_Z, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_RISING), + st->thresh_timestamp); if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_LOW) - iio_push_event(st->indio_dev, 0, - IIO_EVENT_CODE_ACCEL_Z_LOW, - st->last_timestamp); + iio_push_event(st->help.indio_dev, 0, + IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL, + 0, + IIO_EV_MOD_Z, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_FALLING), + st->thresh_timestamp); if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_HIGH) - iio_push_event(st->indio_dev, 0, - IIO_EVENT_CODE_ACCEL_Y_HIGH, - st->last_timestamp); + iio_push_event(st->help.indio_dev, 0, + IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL, + 0, + IIO_EV_MOD_Y, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_RISING), + st->thresh_timestamp); if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_LOW) - iio_push_event(st->indio_dev, 0, - IIO_EVENT_CODE_ACCEL_Y_LOW, - st->last_timestamp); + iio_push_event(st->help.indio_dev, 0, + IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL, + 0, + IIO_EV_MOD_Y, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_FALLING), + st->thresh_timestamp); if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_HIGH) - iio_push_event(st->indio_dev, 0, - IIO_EVENT_CODE_ACCEL_X_HIGH, - st->last_timestamp); + iio_push_event(st->help.indio_dev, 0, + IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL, + 0, + IIO_EV_MOD_X, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_RISING), + st->thresh_timestamp); if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_LOW) - iio_push_event(st->indio_dev, 0, - IIO_EVENT_CODE_ACCEL_X_LOW, - st->last_timestamp); + iio_push_event(st->help.indio_dev, 0, + IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL, + 0, + IIO_EV_MOD_X, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_FALLING), + st->thresh_timestamp); /* reenable the irq */ enable_irq(st->us->irq); /* Ack and allow for new interrupts */ - lis3l02dq_spi_read_reg_8(&st->indio_dev->dev, + lis3l02dq_spi_read_reg_8(&st->help.indio_dev->dev, LIS3L02DQ_REG_WAKE_UP_ACK_ADDR, &t); @@ -666,37 +703,37 @@ static void lis3l02dq_thresh_handler_bh_no_check(struct work_struct *work_s) /* A shared handler for a number of threshold types */ IIO_EVENT_SH(threshold, &lis3l02dq_thresh_handler_th); -IIO_EVENT_ATTR_SH(accel_x_mag_pos_rising_en, +IIO_EVENT_ATTR_SH(accel_x_thresh_rising_en, iio_event_threshold, lis3l02dq_read_interrupt_config, lis3l02dq_write_interrupt_config, LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_X_HIGH); -IIO_EVENT_ATTR_SH(accel_y_mag_pos_rising_en, +IIO_EVENT_ATTR_SH(accel_y_thresh_rising_en, iio_event_threshold, lis3l02dq_read_interrupt_config, lis3l02dq_write_interrupt_config, LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Y_HIGH); -IIO_EVENT_ATTR_SH(accel_z_mag_pos_rising_en, +IIO_EVENT_ATTR_SH(accel_z_thresh_rising_en, iio_event_threshold, lis3l02dq_read_interrupt_config, lis3l02dq_write_interrupt_config, LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Z_HIGH); -IIO_EVENT_ATTR_SH(accel_x_mag_neg_rising_en, +IIO_EVENT_ATTR_SH(accel_x_thresh_falling_en, iio_event_threshold, lis3l02dq_read_interrupt_config, lis3l02dq_write_interrupt_config, LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_X_LOW); -IIO_EVENT_ATTR_SH(accel_y_mag_neg_rising_en, +IIO_EVENT_ATTR_SH(accel_y_thresh_falling_en, iio_event_threshold, lis3l02dq_read_interrupt_config, lis3l02dq_write_interrupt_config, LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Y_LOW); -IIO_EVENT_ATTR_SH(accel_z_mag_neg_rising_en, +IIO_EVENT_ATTR_SH(accel_z_thresh_falling_en, iio_event_threshold, lis3l02dq_read_interrupt_config, lis3l02dq_write_interrupt_config, @@ -704,13 +741,13 @@ IIO_EVENT_ATTR_SH(accel_z_mag_neg_rising_en, static struct attribute *lis3l02dq_event_attributes[] = { - &iio_event_attr_accel_x_mag_pos_rising_en.dev_attr.attr, - &iio_event_attr_accel_y_mag_pos_rising_en.dev_attr.attr, - &iio_event_attr_accel_z_mag_pos_rising_en.dev_attr.attr, - &iio_event_attr_accel_x_mag_neg_rising_en.dev_attr.attr, - &iio_event_attr_accel_y_mag_neg_rising_en.dev_attr.attr, - &iio_event_attr_accel_z_mag_neg_rising_en.dev_attr.attr, - &iio_dev_attr_accel_mag_either_rising_value.dev_attr.attr, + &iio_event_attr_accel_x_thresh_rising_en.dev_attr.attr, + &iio_event_attr_accel_y_thresh_rising_en.dev_attr.attr, + &iio_event_attr_accel_z_thresh_rising_en.dev_attr.attr, + &iio_event_attr_accel_x_thresh_falling_en.dev_attr.attr, + &iio_event_attr_accel_y_thresh_falling_en.dev_attr.attr, + &iio_event_attr_accel_z_thresh_falling_en.dev_attr.attr, + &iio_dev_attr_accel_raw_mag_value.dev_attr.attr, NULL }; @@ -718,7 +755,7 @@ static struct attribute_group lis3l02dq_event_attribute_group = { .attrs = lis3l02dq_event_attributes, }; -static IIO_CONST_ATTR(name, "lis3l02dq"); +static IIO_CONST_ATTR_NAME("lis3l02dq"); static IIO_CONST_ATTR(accel_scale, "0.00958"); static struct attribute *lis3l02dq_attributes[] = { @@ -750,6 +787,7 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi) ret = -ENOMEM; goto error_ret; } + INIT_WORK(&st->work_thresh, lis3l02dq_thresh_handler_bh_no_check); /* this is only used tor removal purposes */ spi_set_drvdata(spi, st); @@ -767,56 +805,46 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi) st->us = spi; mutex_init(&st->buf_lock); /* setup the industrialio driver allocated elements */ - st->indio_dev = iio_allocate_device(); - if (st->indio_dev == NULL) { + st->help.indio_dev = iio_allocate_device(); + if (st->help.indio_dev == NULL) { ret = -ENOMEM; goto error_free_tx; } - st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->num_interrupt_lines = 1; - st->indio_dev->event_attrs = &lis3l02dq_event_attribute_group; - st->indio_dev->attrs = &lis3l02dq_attribute_group; - st->indio_dev->dev_data = (void *)(st); - st->indio_dev->driver_module = THIS_MODULE; - st->indio_dev->modes = INDIO_DIRECT_MODE; + st->help.indio_dev->dev.parent = &spi->dev; + st->help.indio_dev->num_interrupt_lines = 1; + st->help.indio_dev->event_attrs = &lis3l02dq_event_attribute_group; + st->help.indio_dev->attrs = &lis3l02dq_attribute_group; + st->help.indio_dev->dev_data = (void *)(&st->help); + st->help.indio_dev->driver_module = THIS_MODULE; + st->help.indio_dev->modes = INDIO_DIRECT_MODE; - ret = lis3l02dq_configure_ring(st->indio_dev); + ret = lis3l02dq_configure_ring(st->help.indio_dev); if (ret) goto error_free_dev; - ret = iio_device_register(st->indio_dev); + ret = iio_device_register(st->help.indio_dev); if (ret) goto error_unreg_ring_funcs; regdone = 1; - ret = lis3l02dq_initialize_ring(st->indio_dev->ring); + ret = iio_ring_buffer_register(st->help.indio_dev->ring, 0); if (ret) { printk(KERN_ERR "failed to initialize the ring\n"); goto error_unreg_ring_funcs; } if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) { - /* This is a little unusual, in that the device seems - to need a full read of the interrupt source reg before - the interrupt will reset. - Hence the two handlers are the same */ - iio_init_work_cont(&st->work_cont_thresh, - lis3l02dq_thresh_handler_bh_no_check, - lis3l02dq_thresh_handler_bh_no_check, - LIS3L02DQ_REG_WAKE_UP_SRC_ADDR, - 0, - st); st->inter = 0; ret = iio_register_interrupt_line(spi->irq, - st->indio_dev, + st->help.indio_dev, 0, IRQF_TRIGGER_RISING, "lis3l02dq"); if (ret) goto error_uninitialize_ring; - ret = lis3l02dq_probe_trigger(st->indio_dev); + ret = lis3l02dq_probe_trigger(st->help.indio_dev); if (ret) goto error_unregister_line; } @@ -828,20 +856,20 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi) return 0; error_remove_trigger: - if (st->indio_dev->modes & INDIO_RING_TRIGGERED) - lis3l02dq_remove_trigger(st->indio_dev); + if (st->help.indio_dev->modes & INDIO_RING_TRIGGERED) + lis3l02dq_remove_trigger(st->help.indio_dev); error_unregister_line: - if (st->indio_dev->modes & INDIO_RING_TRIGGERED) - iio_unregister_interrupt_line(st->indio_dev, 0); + if (st->help.indio_dev->modes & INDIO_RING_TRIGGERED) + iio_unregister_interrupt_line(st->help.indio_dev, 0); error_uninitialize_ring: - lis3l02dq_uninitialize_ring(st->indio_dev->ring); + iio_ring_buffer_unregister(st->help.indio_dev->ring); error_unreg_ring_funcs: - lis3l02dq_unconfigure_ring(st->indio_dev); + lis3l02dq_unconfigure_ring(st->help.indio_dev); error_free_dev: if (regdone) - iio_device_unregister(st->indio_dev); + iio_device_unregister(st->help.indio_dev); else - iio_free_device(st->indio_dev); + iio_free_device(st->help.indio_dev); error_free_tx: kfree(st->tx); error_free_rx: @@ -856,7 +884,9 @@ error_ret: static int lis3l02dq_stop_device(struct iio_dev *indio_dev) { int ret; - struct lis3l02dq_state *st = indio_dev->dev_data; + struct iio_sw_ring_helper_state *h + = iio_dev_get_devdata(indio_dev); + struct lis3l02dq_state *st = lis3l02dq_h_to_s(h); u8 val = 0; mutex_lock(&indio_dev->mlock); @@ -883,7 +913,7 @@ static int lis3l02dq_remove(struct spi_device *spi) { int ret; struct lis3l02dq_state *st = spi_get_drvdata(spi); - struct iio_dev *indio_dev = st->indio_dev; + struct iio_dev *indio_dev = st->help.indio_dev; ret = lis3l02dq_stop_device(indio_dev); if (ret) @@ -895,7 +925,7 @@ static int lis3l02dq_remove(struct spi_device *spi) if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) iio_unregister_interrupt_line(indio_dev, 0); - lis3l02dq_uninitialize_ring(indio_dev->ring); + iio_ring_buffer_unregister(indio_dev->ring); lis3l02dq_unconfigure_ring(indio_dev); iio_device_unregister(indio_dev); kfree(st->tx); diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index e4e202e6cb3a..330d5d6dbba4 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -75,22 +75,30 @@ error_ret: return ret; } -static IIO_SCAN_EL_C(accel_x, 0, IIO_SIGNED(16), +static IIO_SCAN_EL_C(accel_x, 0, LIS3L02DQ_REG_OUT_X_L_ADDR, &lis3l02dq_scan_el_set_state); -static IIO_SCAN_EL_C(accel_y, 1, IIO_SIGNED(16), +static IIO_SCAN_EL_C(accel_y, 1, LIS3L02DQ_REG_OUT_Y_L_ADDR, &lis3l02dq_scan_el_set_state); -static IIO_SCAN_EL_C(accel_z, 2, IIO_SIGNED(16), +static IIO_SCAN_EL_C(accel_z, 2, LIS3L02DQ_REG_OUT_Z_L_ADDR, &lis3l02dq_scan_el_set_state); +static IIO_CONST_ATTR_SCAN_EL_TYPE(accel, s, 12, 16); static IIO_SCAN_EL_TIMESTAMP(3); +static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64); static struct attribute *lis3l02dq_scan_el_attrs[] = { &iio_scan_el_accel_x.dev_attr.attr, + &iio_const_attr_accel_x_index.dev_attr.attr, &iio_scan_el_accel_y.dev_attr.attr, + &iio_const_attr_accel_y_index.dev_attr.attr, &iio_scan_el_accel_z.dev_attr.attr, + &iio_const_attr_accel_z_index.dev_attr.attr, + &iio_const_attr_accel_type.dev_attr.attr, &iio_scan_el_timestamp.dev_attr.attr, + &iio_const_attr_timestamp_index.dev_attr.attr, + &iio_const_attr_timestamp_type.dev_attr.attr, NULL, }; @@ -103,13 +111,15 @@ static struct attribute_group lis3l02dq_scan_el_group = { * lis3l02dq_poll_func_th() top half interrupt handler called by trigger * @private_data: iio_dev **/ -static void lis3l02dq_poll_func_th(struct iio_dev *indio_dev) +static void lis3l02dq_poll_func_th(struct iio_dev *indio_dev, s64 time) { - struct lis3l02dq_state *st = iio_dev_get_devdata(indio_dev); - st->last_timestamp = indio_dev->trig->timestamp; - schedule_work(&st->work_trigger_to_ring); - /* Indicate that this interrupt is being handled */ + struct iio_sw_ring_helper_state *h + = iio_dev_get_devdata(indio_dev); + struct lis3l02dq_state *st = lis3l02dq_h_to_s(h); + /* in this case we need to slightly extend the helper function */ + iio_sw_poll_func_th(indio_dev, time); + /* Indicate that this interrupt is being handled */ /* Technically this is trigger related, but without this * handler running there is currently now way for the interrupt * to clear. @@ -120,16 +130,16 @@ static void lis3l02dq_poll_func_th(struct iio_dev *indio_dev) /** * lis3l02dq_data_rdy_trig_poll() the event handler for the data rdy trig **/ -static int lis3l02dq_data_rdy_trig_poll(struct iio_dev *dev_info, +static int lis3l02dq_data_rdy_trig_poll(struct iio_dev *indio_dev, int index, s64 timestamp, int no_test) { - struct lis3l02dq_state *st = iio_dev_get_devdata(dev_info); - struct iio_trigger *trig = st->trig; + struct iio_sw_ring_helper_state *h + = iio_dev_get_devdata(indio_dev); + struct lis3l02dq_state *st = lis3l02dq_h_to_s(h); - trig->timestamp = timestamp; - iio_trigger_poll(trig); + iio_trigger_poll(st->trig, timestamp); return IRQ_HANDLED; } @@ -148,38 +158,40 @@ ssize_t lis3l02dq_read_accel_from_ring(struct device *dev, int ret, len = 0, i = 0; struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_ring_buffer *ring = dev_info->ring; + struct attribute_group *scan_el_attrs = ring->scan_el_attrs; s16 *data; - while (dev_info->scan_el_attrs->attrs[i]) { + while (scan_el_attrs->attrs[i]) { el = to_iio_scan_el((struct device_attribute *) - (dev_info->scan_el_attrs->attrs[i])); + (scan_el_attrs->attrs[i])); /* label is in fact the address */ if (el->label == this_attr->address) break; i++; } - if (!dev_info->scan_el_attrs->attrs[i]) { + if (!scan_el_attrs->attrs[i]) { ret = -EINVAL; goto error_ret; } /* If this element is in the scan mask */ - ret = iio_scan_mask_query(dev_info, el->number); + ret = iio_scan_mask_query(ring, el->number); if (ret < 0) goto error_ret; if (ret) { - data = kmalloc(dev_info->ring->access.get_bpd(dev_info->ring), + data = kmalloc(ring->access.get_bytes_per_datum(ring), GFP_KERNEL); if (data == NULL) return -ENOMEM; - ret = dev_info->ring->access.read_last(dev_info->ring, - (u8 *)data); + ret = ring->access.read_last(ring, + (u8 *)data); if (ret) goto error_free_data; } else { ret = -EINVAL; goto error_ret; } - len = iio_scan_mask_count_to_right(dev_info, el->number); + len = iio_scan_mask_count_to_right(ring, el->number); if (len < 0) { ret = len; goto error_free_data; @@ -209,11 +221,12 @@ static const u8 read_all_tx_array[] = { **/ static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array) { + struct iio_ring_buffer *ring = st->help.indio_dev->ring; struct spi_transfer *xfers; struct spi_message msg; int ret, i, j = 0; - xfers = kzalloc((st->indio_dev->scan_count) * 2 + xfers = kzalloc((ring->scan_count) * 2 * sizeof(*xfers), GFP_KERNEL); if (!xfers) return -ENOMEM; @@ -221,7 +234,7 @@ static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array) mutex_lock(&st->buf_lock); for (i = 0; i < ARRAY_SIZE(read_all_tx_array)/4; i++) { - if (st->indio_dev->scan_mask & (1 << i)) { + if (ring->scan_mask & (1 << i)) { /* lower byte */ xfers[j].tx_buf = st->tx + 2*j; st->tx[2*j] = read_all_tx_array[i*4]; @@ -249,7 +262,7 @@ static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array) * values in alternate bytes */ spi_message_init(&msg); - for (j = 0; j < st->indio_dev->scan_count * 2; j++) + for (j = 0; j < ring->scan_count * 2; j++) spi_message_add_tail(&xfers[j], &msg); ret = spi_sync(st->us, &msg); @@ -259,102 +272,37 @@ static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array) 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 void lis3l02dq_trigger_bh_to_ring(struct work_struct *work_s) { - struct lis3l02dq_state *st - = container_of(work_s, struct lis3l02dq_state, - work_trigger_to_ring); - - u8 *rx_array; - int i = 0; - u16 *data; - size_t datasize = st->indio_dev - ->ring->access.get_bpd(st->indio_dev->ring); - - data = kmalloc(datasize , GFP_KERNEL); - if (data == NULL) { - dev_err(&st->us->dev, "memory alloc failed in ring bh"); - return; - } - /* Due to interleaved nature of transmission this buffer must be - * twice the number of bytes, or 4 times the number of channels - */ - rx_array = kmalloc(4 * (st->indio_dev->scan_count), GFP_KERNEL); - if (rx_array == NULL) { - dev_err(&st->us->dev, "memory alloc failed in ring bh"); - kfree(data); - return; - } + struct iio_sw_ring_helper_state *h + = container_of(work_s, struct iio_sw_ring_helper_state, + work_trigger_to_ring); + struct lis3l02dq_state *st = lis3l02dq_h_to_s(h); - /* whilst trigger specific, if this read does nto occur the data - ready interrupt will not be cleared. Need to add a mechanism - to provide a dummy read function if this is not triggering on - the data ready function but something else is. - */ st->inter = 0; - - if (st->indio_dev->scan_count) - if (lis3l02dq_read_all(st, rx_array) >= 0) - for (; i < st->indio_dev->scan_count; i++) - data[i] = combine_8_to_16(rx_array[i*4+1], - rx_array[i*4+3]); - /* Guaranteed to be aligned with 8 byte boundary */ - if (st->indio_dev->scan_timestamp) - *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp; - - st->indio_dev->ring->access.store_to(st->indio_dev->ring, - (u8 *)data, - st->last_timestamp); - - iio_trigger_notify_done(st->indio_dev->trig); - kfree(rx_array); - kfree(data); - - return; + iio_sw_trigger_bh_to_ring(work_s); } -/* in these circumstances is it better to go with unaligned packing and - * deal with the cost?*/ -static int lis3l02dq_data_rdy_ring_preenable(struct iio_dev *indio_dev) -{ - size_t size; - /* Check if there are any scan elements enabled, if not fail*/ - if (!(indio_dev->scan_count || indio_dev->scan_timestamp)) - return -EINVAL; - - if (indio_dev->ring->access.set_bpd) { - if (indio_dev->scan_timestamp) - if (indio_dev->scan_count) /* Timestamp and data */ - size = 2*sizeof(s64); - else /* Timestamp only */ - size = sizeof(s64); - else /* Data only */ - size = indio_dev->scan_count*sizeof(s16); - indio_dev->ring->access.set_bpd(indio_dev->ring, size); - } - return 0; -} - -static int lis3l02dq_data_rdy_ring_postenable(struct iio_dev *indio_dev) +static int lis3l02dq_get_ring_element(struct iio_sw_ring_helper_state *h, + u8 *buf) { - return indio_dev->trig - ? iio_trigger_attach_poll_func(indio_dev->trig, - indio_dev->pollfunc) - : 0; -} + int ret, i; + u8 *rx_array ; + s16 *data = (s16 *)buf; -static int lis3l02dq_data_rdy_ring_predisable(struct iio_dev *indio_dev) -{ - return indio_dev->trig - ? iio_trigger_dettach_poll_func(indio_dev->trig, - indio_dev->pollfunc) - : 0; -} + rx_array = kzalloc(4 * (h->indio_dev->ring->scan_count), GFP_KERNEL); + if (rx_array == NULL) + return -ENOMEM; + ret = lis3l02dq_read_all(lis3l02dq_h_to_s(h), rx_array); + if (ret < 0) + return ret; + for (i = 0; i < h->indio_dev->ring->scan_count; i++) + data[i] = combine_8_to_16(rx_array[i*4+1], + rx_array[i*4+3]); + kfree(rx_array); + return i*sizeof(data[0]); +} /* Caller responsible for locking as necessary. */ static int @@ -427,7 +375,7 @@ static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig, struct lis3l02dq_state *st = trig->private_data; int ret = 0; u8 t; - __lis3l02dq_write_data_ready_config(&st->indio_dev->dev, + __lis3l02dq_write_data_ready_config(&st->help.indio_dev->dev, &iio_event_data_rdy_trig, state); if (state == false) { @@ -437,12 +385,13 @@ static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig, /* Clear any outstanding ready events */ ret = lis3l02dq_read_all(st, NULL); } - lis3l02dq_spi_read_reg_8(&st->indio_dev->dev, + lis3l02dq_spi_read_reg_8(&st->help.indio_dev->dev, LIS3L02DQ_REG_WAKE_UP_SRC_ADDR, &t); return ret; } -static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL); + +static IIO_TRIGGER_NAME_ATTR; static struct attribute *lis3l02dq_trigger_attrs[] = { &dev_attr_name.attr, @@ -495,14 +444,14 @@ int lis3l02dq_probe_trigger(struct iio_dev *indio_dev) if (!state->trig) return -ENOMEM; - state->trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH, GFP_KERNEL); + state->trig->name = kasprintf(GFP_KERNEL, + "lis3l02dq-dev%d", + indio_dev->id); if (!state->trig->name) { ret = -ENOMEM; goto error_free_trig; } - snprintf((char *)state->trig->name, - IIO_TRIGGER_NAME_LENGTH, - "lis3l02dq-dev%d", indio_dev->id); + state->trig->dev.parent = &state->us->dev; state->trig->owner = THIS_MODULE; state->trig->private_data = state; @@ -540,39 +489,35 @@ void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev) int lis3l02dq_configure_ring(struct iio_dev *indio_dev) { - int ret = 0; - struct lis3l02dq_state *st = indio_dev->dev_data; + int ret; + struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev); struct iio_ring_buffer *ring; - INIT_WORK(&st->work_trigger_to_ring, lis3l02dq_trigger_bh_to_ring); - /* Set default scan mode */ - - iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number); - iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number); - iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number); - indio_dev->scan_timestamp = true; - - indio_dev->scan_el_attrs = &lis3l02dq_scan_el_group; + INIT_WORK(&h->work_trigger_to_ring, lis3l02dq_trigger_bh_to_ring); + h->get_ring_element = &lis3l02dq_get_ring_element; ring = iio_sw_rb_allocate(indio_dev); - if (!ring) { - ret = -ENOMEM; - return ret; - } + if (!ring) + return -ENOMEM; + indio_dev->ring = ring; /* Effectively select the ring buffer implementation */ iio_ring_sw_register_funcs(&ring->access); - ring->preenable = &lis3l02dq_data_rdy_ring_preenable; - ring->postenable = &lis3l02dq_data_rdy_ring_postenable; - ring->predisable = &lis3l02dq_data_rdy_ring_predisable; + ring->bpe = 2; + ring->scan_el_attrs = &lis3l02dq_scan_el_group; + ring->scan_timestamp = true; + ring->preenable = &iio_sw_ring_preenable; + ring->postenable = &iio_triggered_ring_postenable; + ring->predisable = &iio_triggered_ring_predisable; ring->owner = THIS_MODULE; - indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL); - if (indio_dev->pollfunc == NULL) { - ret = -ENOMEM; + /* Set default scan mode */ + iio_scan_mask_set(ring, iio_scan_el_accel_x.number); + iio_scan_mask_set(ring, iio_scan_el_accel_y.number); + iio_scan_mask_set(ring, iio_scan_el_accel_z.number); + + ret = iio_alloc_pollfunc(indio_dev, NULL, &lis3l02dq_poll_func_th); + if (ret) goto error_iio_sw_rb_free;; - } - indio_dev->pollfunc->poll_func_main = &lis3l02dq_poll_func_th; - indio_dev->pollfunc->private_data = indio_dev; indio_dev->modes |= INDIO_RING_TRIGGERED; return 0; @@ -580,23 +525,3 @@ error_iio_sw_rb_free: iio_sw_rb_free(indio_dev->ring); return ret; } - -int lis3l02dq_initialize_ring(struct iio_ring_buffer *ring) -{ - return iio_ring_buffer_register(ring, 0); -} - -void lis3l02dq_uninitialize_ring(struct iio_ring_buffer *ring) -{ - iio_ring_buffer_unregister(ring); -} - -int lis3l02dq_set_ring_length(struct iio_dev *indio_dev, int length) -{ - /* Set sensible defaults for the ring buffer */ - if (indio_dev->ring->access.set_length) - return indio_dev->ring->access.set_length(indio_dev->ring, 500); - return 0; -} - - diff --git a/drivers/staging/iio/accel/sca3000.h b/drivers/staging/iio/accel/sca3000.h index e5321999b263..23892848f5ae 100644 --- a/drivers/staging/iio/accel/sca3000.h +++ b/drivers/staging/iio/accel/sca3000.h @@ -91,7 +91,7 @@ #define SCA3000_INT_STATUS_X_TRIGGER 0x02 #define SCA3000_INT_STATUS_Z_TRIGGER 0x01 -/* Used to allow accesss to multiplexed registers */ +/* Used to allow access to multiplexed registers */ #define SCA3000_REG_ADDR_CTRL_SEL 0x18 /* Only available for SCA3000-D03 and SCA3000-D01 */ #define SCA3000_REG_CTRL_SEL_I2C_DISABLE 0x01 @@ -242,7 +242,7 @@ static inline int sca3000_11bit_convert(uint8_t msb, uint8_t lsb) val |= (val & (1 << 12)) ? 0xE000 : 0; return val; -}; +} static inline int sca3000_13bit_convert(uint8_t msb, uint8_t lsb) { @@ -253,7 +253,7 @@ static inline int sca3000_13bit_convert(uint8_t msb, uint8_t lsb) val |= (val & (1 << 12)) ? 0xE000 : 0; return val; -}; +} #ifdef CONFIG_IIO_RING_BUFFER @@ -286,15 +286,19 @@ void sca3000_unconfigure_ring(struct iio_dev *indio_dev); void sca3000_ring_int_process(u8 val, struct iio_ring_buffer *ring); #else -static inline void sca3000_register_ring_funcs(struct iio_dev *indio_dev) {}; +static inline void sca3000_register_ring_funcs(struct iio_dev *indio_dev) +{ +} static inline int sca3000_register_ring_access_and_init(struct iio_dev *indio_dev) { return 0; -}; +} -static inline void sca3000_ring_int_process(u8 val, void *ring) {}; +static inline void sca3000_ring_int_process(u8 val, void *ring) +{ +} #endif diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c index d4f82c39f335..5b06dea6af25 100644 --- a/drivers/staging/iio/accel/sca3000_core.c +++ b/drivers/staging/iio/accel/sca3000_core.c @@ -387,7 +387,7 @@ sca3000_show_available_measurement_modes(struct device *dev, case SCA3000_OP_MODE_BYPASS: len += sprintf(buf + len, ", 1 - bypass mode"); break; - }; + } switch (st->info->option_mode_2) { case SCA3000_OP_MODE_WIDE: len += sprintf(buf + len, ", 2 - wide mode"); @@ -433,7 +433,7 @@ sca3000_show_measurement_mode(struct device *dev, case SCA3000_OP_MODE_BYPASS: len += sprintf(buf + len, "1 - bypass mode\n"); break; - }; + } break; case SCA3000_MEAS_MODE_OP_2: switch (st->info->option_mode_2) { @@ -442,7 +442,7 @@ sca3000_show_measurement_mode(struct device *dev, break; } break; - }; + } error_ret: mutex_unlock(&st->lock); @@ -559,7 +559,7 @@ static ssize_t sca3000_read_av_freq(struct device *dev, st->info->option_mode_2_freq/2, st->info->option_mode_2_freq/4); break; - }; + } kfree(rx); return len; error_ret: @@ -590,7 +590,7 @@ static inline int __sca3000_get_base_freq(struct sca3000_state *st, case SCA3000_MEAS_MODE_OP_2: *base_freq = info->option_mode_2_freq; break; - }; + } kfree(rx); error_ret: return ret; @@ -627,8 +627,8 @@ static ssize_t sca3000_read_frequency(struct device *dev, case 0x02: len = sprintf(buf, "%d\n", base_freq/4); break; - }; - kfree(rx); + } + kfree(rx); return len; error_ret_mut: mutex_unlock(&st->lock); @@ -721,8 +721,8 @@ error_ret: } static IIO_DEV_ATTR_TEMP_RAW(sca3000_read_temp); -static IIO_CONST_ATTR(temp_scale, "0.555556"); -static IIO_CONST_ATTR(temp_offset, "-214.6"); +static IIO_CONST_ATTR_TEMP_SCALE("0.555556"); +static IIO_CONST_ATTR_TEMP_OFFSET("-214.6"); /** * sca3000_show_thresh() sysfs query of a threshold @@ -774,19 +774,19 @@ static ssize_t sca3000_write_thresh(struct device *dev, return ret ? ret : len; } -static IIO_DEVICE_ATTR(accel_x_mag_either_rising_value, +static IIO_DEVICE_ATTR(accel_x_raw_mag_rising_value, S_IRUGO | S_IWUSR, sca3000_show_thresh, sca3000_write_thresh, SCA3000_REG_CTRL_SEL_MD_X_TH); -static IIO_DEVICE_ATTR(accel_y_mag_either_rising_value, +static IIO_DEVICE_ATTR(accel_y_raw_mag_rising_value, S_IRUGO | S_IWUSR, sca3000_show_thresh, sca3000_write_thresh, SCA3000_REG_CTRL_SEL_MD_Y_TH); -static IIO_DEVICE_ATTR(accel_z_mag_either_rising_value, +static IIO_DEVICE_ATTR(accel_z_raw_mag_rising_value, S_IRUGO | S_IWUSR, sca3000_show_thresh, sca3000_write_thresh, @@ -865,22 +865,38 @@ static void sca3000_interrupt_handler_bh(struct work_struct *work_s) if (rx[1] & SCA3000_INT_STATUS_FREE_FALL) iio_push_event(st->indio_dev, 0, - IIO_EVENT_CODE_FREE_FALL, + IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL, + 0, + IIO_EV_MOD_X_AND_Y_AND_Z, + IIO_EV_TYPE_MAG, + IIO_EV_DIR_FALLING), st->last_timestamp); if (rx[1] & SCA3000_INT_STATUS_Y_TRIGGER) iio_push_event(st->indio_dev, 0, - IIO_EVENT_CODE_ACCEL_Y_HIGH, + IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL, + 0, + IIO_EV_MOD_Y, + IIO_EV_TYPE_MAG, + IIO_EV_DIR_RISING), st->last_timestamp); if (rx[1] & SCA3000_INT_STATUS_X_TRIGGER) iio_push_event(st->indio_dev, 0, - IIO_EVENT_CODE_ACCEL_X_HIGH, + IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL, + 0, + IIO_EV_MOD_X, + IIO_EV_TYPE_MAG, + IIO_EV_DIR_RISING), st->last_timestamp); if (rx[1] & SCA3000_INT_STATUS_Z_TRIGGER) iio_push_event(st->indio_dev, 0, - IIO_EVENT_CODE_ACCEL_Z_HIGH, + IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL, + 0, + IIO_EV_MOD_Z, + IIO_EV_TYPE_MAG, + IIO_EV_DIR_RISING), st->last_timestamp); done: @@ -1156,25 +1172,31 @@ exit_point: IIO_EVENT_SH(all, &sca3000_handler_th); /* Free fall detector related event attribute */ -IIO_EVENT_ATTR_FREE_FALL_DETECT_SH(iio_event_all, - sca3000_query_free_fall_mode, - sca3000_set_free_fall_mode, - 0) +IIO_EVENT_ATTR_NAMED_SH(accel_xayaz_mag_falling_en, + accel_x&y&z_mag_falling_en, + iio_event_all, + sca3000_query_free_fall_mode, + sca3000_set_free_fall_mode, + 0); + +IIO_CONST_ATTR_NAMED(accel_xayaz_mag_falling_period, + accel_x&y&z_mag_falling_period, + "0.226"); /* Motion detector related event attributes */ -IIO_EVENT_ATTR_SH(accel_x_mag_either_rising_en, +IIO_EVENT_ATTR_SH(accel_x_mag_rising_en, iio_event_all, sca3000_query_mo_det, sca3000_set_mo_det, SCA3000_MD_CTRL_OR_X); -IIO_EVENT_ATTR_SH(accel_y_mag_either_rising_en, +IIO_EVENT_ATTR_SH(accel_y_mag_rising_en, iio_event_all, sca3000_query_mo_det, sca3000_set_mo_det, SCA3000_MD_CTRL_OR_Y); -IIO_EVENT_ATTR_SH(accel_z_mag_either_rising_en, +IIO_EVENT_ATTR_SH(accel_z_mag_rising_en, iio_event_all, sca3000_query_mo_det, sca3000_set_mo_det, @@ -1192,15 +1214,16 @@ IIO_EVENT_ATTR_RING_75_FULL_SH(iio_event_all, SCA3000_INT_MASK_RING_THREE_QUARTER); static struct attribute *sca3000_event_attributes[] = { - &iio_event_attr_free_fall.dev_attr.attr, - &iio_event_attr_accel_x_mag_either_rising_en.dev_attr.attr, - &iio_event_attr_accel_y_mag_either_rising_en.dev_attr.attr, - &iio_event_attr_accel_z_mag_either_rising_en.dev_attr.attr, + &iio_event_attr_accel_xayaz_mag_falling_en.dev_attr.attr, + &iio_const_attr_accel_xayaz_mag_falling_period.dev_attr.attr, + &iio_event_attr_accel_x_mag_rising_en.dev_attr.attr, + &iio_dev_attr_accel_x_raw_mag_rising_value.dev_attr.attr, + &iio_event_attr_accel_y_mag_rising_en.dev_attr.attr, + &iio_dev_attr_accel_y_raw_mag_rising_value.dev_attr.attr, + &iio_event_attr_accel_z_mag_rising_en.dev_attr.attr, + &iio_dev_attr_accel_z_raw_mag_rising_value.dev_attr.attr, &iio_event_attr_ring_50_full.dev_attr.attr, &iio_event_attr_ring_75_full.dev_attr.attr, - &iio_dev_attr_accel_x_mag_either_rising_value.dev_attr.attr, - &iio_dev_attr_accel_y_mag_either_rising_value.dev_attr.attr, - &iio_dev_attr_accel_z_mag_either_rising_value.dev_attr.attr, NULL, }; @@ -1358,7 +1381,7 @@ static int __devinit __sca3000_probe(struct spi_device *spi, * might be worthwhile. */ iio_add_event_to_list( - iio_event_attr_accel_z_mag_either_rising_en.listel, + iio_event_attr_accel_z_mag_rising_en.listel, &st->indio_dev ->interrupts[0]->ev_list); } diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c index 8e8c068d401b..c872fddfb2bf 100644 --- a/drivers/staging/iio/accel/sca3000_ring.c +++ b/drivers/staging/iio/accel/sca3000_ring.c @@ -53,7 +53,8 @@ static int sca3000_rip_hw_rb(struct iio_ring_buffer *r, struct iio_dev *indio_dev = hw_ring->private; struct sca3000_state *st = indio_dev->dev_data; u8 *rx; - int ret, num_available, num_read = 0; + s16 *samples; + int ret, i, num_available, num_read = 0; int bytes_per_sample = 1; if (st->bpse == 11) @@ -87,6 +88,17 @@ static int sca3000_rip_hw_rb(struct iio_ring_buffer *r, ret = sca3000_read_data(st, SCA3000_REG_ADDR_RING_OUT, data, num_read); + + /* Convert byte order and shift to default resolution */ + if (st->bpse == 11) { + samples = (s16*)(*data+1); + for (i = 0; i < (num_read/2); i++) { + samples[i] = be16_to_cpup( + (__be16 *)&(samples[i])); + samples[i] >>= 3; + } + } + error_ret: mutex_unlock(&st->lock); @@ -100,7 +112,7 @@ static int sca3000_ring_get_length(struct iio_ring_buffer *r) } /* only valid if resolution is kept at 11bits */ -static int sca3000_ring_get_bpd(struct iio_ring_buffer *r) +static int sca3000_ring_get_bytes_per_datum(struct iio_ring_buffer *r) { return 6; } @@ -111,7 +123,7 @@ static void sca3000_ring_release(struct device *dev) } static IIO_RING_ENABLE_ATTR; -static IIO_RING_BPS_ATTR; +static IIO_RING_BYTES_PER_DATUM_ATTR; static IIO_RING_LENGTH_ATTR; /** @@ -126,14 +138,18 @@ static ssize_t sca3000_show_ring_bpse(struct device *dev, { int len = 0, ret; u8 *rx; - struct iio_ring_buffer *r = dev_get_drvdata(dev); - struct sca3000_state *st = r->indio_dev->dev_data; + struct iio_ring_buffer *ring = dev_get_drvdata(dev); + struct iio_dev *indio_dev = ring->indio_dev; + struct sca3000_state *st = indio_dev->dev_data; mutex_lock(&st->lock); ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1); if (ret) goto error_ret; - len = sprintf(buf, "%d\n", (rx[1] & SCA3000_RING_BUF_8BIT) ? 8 : 11); + if (rx[1] & SCA3000_RING_BUF_8BIT) + len = sprintf(buf, "s8/8\n"); + else + len = sprintf(buf, "s11/16\n"); kfree(rx); error_ret: mutex_unlock(&st->lock); @@ -153,44 +169,38 @@ static ssize_t sca3000_store_ring_bpse(struct device *dev, const char *buf, size_t len) { - struct iio_ring_buffer *r = dev_get_drvdata(dev); - struct sca3000_state *st = r->indio_dev->dev_data; + struct iio_ring_buffer *ring = dev_get_drvdata(dev); + struct iio_dev *indio_dev = ring->indio_dev; + struct sca3000_state *st = indio_dev->dev_data; int ret; u8 *rx; - long val; - ret = strict_strtol(buf, 10, &val); - if (ret) - return ret; mutex_lock(&st->lock); ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1); - if (!ret) - switch (val) { - case 8: - ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE, - rx[1] | SCA3000_RING_BUF_8BIT); - st->bpse = 8; - break; - case 11: - ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE, - rx[1] & ~SCA3000_RING_BUF_8BIT); - st->bpse = 11; - break; - default: - ret = -EINVAL; - break; - } + if (ret) + goto error_ret; + if (strncmp(buf, "s8/8", 4) == 0) { + ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE, + rx[1] | SCA3000_RING_BUF_8BIT); + st->bpse = 8; + } else if (strncmp(buf, "s11/16", 5) == 0) { + ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE, + rx[1] & ~SCA3000_RING_BUF_8BIT); + st->bpse = 11; + } else + ret = -EINVAL; +error_ret: mutex_unlock(&st->lock); return ret ? ret : len; } -static IIO_SCAN_EL_C(accel_x, 0, 0, 0, NULL); -static IIO_SCAN_EL_C(accel_y, 1, 0, 0, NULL); -static IIO_SCAN_EL_C(accel_z, 2, 0, 0, NULL); -static IIO_CONST_ATTR(accel_precision_available, "8 11"); -static IIO_DEVICE_ATTR(accel_precision, +static IIO_SCAN_EL_C(accel_x, 0, 0, NULL); +static IIO_SCAN_EL_C(accel_y, 1, 0, NULL); +static IIO_SCAN_EL_C(accel_z, 2, 0, NULL); +static IIO_CONST_ATTR(accel_type_available, "s8/8 s11/16"); +static IIO_DEVICE_ATTR(accel_type, S_IRUGO | S_IWUSR, sca3000_show_ring_bpse, sca3000_store_ring_bpse, @@ -198,10 +208,13 @@ static IIO_DEVICE_ATTR(accel_precision, static struct attribute *sca3000_scan_el_attrs[] = { &iio_scan_el_accel_x.dev_attr.attr, + &iio_const_attr_accel_x_index.dev_attr.attr, &iio_scan_el_accel_y.dev_attr.attr, + &iio_const_attr_accel_y_index.dev_attr.attr, &iio_scan_el_accel_z.dev_attr.attr, - &iio_const_attr_accel_precision_available.dev_attr.attr, - &iio_dev_attr_accel_precision.dev_attr.attr, + &iio_const_attr_accel_z_index.dev_attr.attr, + &iio_const_attr_accel_type_available.dev_attr.attr, + &iio_dev_attr_accel_type.dev_attr.attr, NULL }; @@ -218,8 +231,8 @@ static struct attribute_group sca3000_scan_el_group = { */ static struct attribute *sca3000_ring_attributes[] = { &dev_attr_length.attr, - &dev_attr_bps.attr, - &dev_attr_ring_enable.attr, + &dev_attr_bytes_per_datum.attr, + &dev_attr_enable.attr, NULL, }; @@ -264,15 +277,15 @@ static inline void sca3000_rb_free(struct iio_ring_buffer *r) int sca3000_configure_ring(struct iio_dev *indio_dev) { - indio_dev->scan_el_attrs = &sca3000_scan_el_group; indio_dev->ring = sca3000_rb_allocate(indio_dev); if (indio_dev->ring == NULL) return -ENOMEM; indio_dev->modes |= INDIO_RING_HARDWARE_BUFFER; + indio_dev->ring->scan_el_attrs = &sca3000_scan_el_group; indio_dev->ring->access.rip_lots = &sca3000_rip_hw_rb; indio_dev->ring->access.get_length = &sca3000_ring_get_length; - indio_dev->ring->access.get_bpd = &sca3000_ring_get_bpd; + indio_dev->ring->access.get_bytes_per_datum = &sca3000_ring_get_bytes_per_datum; return 0; } |